mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-01 07:02:48 +08:00
🔀 Merge branch 'trunk'
This commit is contained in:
commit
24ada2c2a5
9 changed files with 221 additions and 116 deletions
|
@ -7,6 +7,5 @@
|
|||
export const STORE_NAME = 'wc/paypal/todos';
|
||||
export const REST_PATH = '/wc/v3/wc_paypal/todos';
|
||||
export const REST_PERSIST_PATH = '/wc/v3/wc_paypal/todos';
|
||||
export const REST_RESET_DISMISSED_TODOS_PATH =
|
||||
'/wc/v3/wc_paypal/reset-dismissed-todos';
|
||||
export const REST_COMPLETE_ONCLICK_PATH = '/wc/v3/wc_paypal/complete-onclick';
|
||||
export const REST_RESET_DISMISSED_TODOS_PATH = '/wc/v3/wc_paypal/todos/reset';
|
||||
export const REST_COMPLETE_ONCLICK_PATH = '/wc/v3/wc_paypal/todos/complete';
|
||||
|
|
|
@ -313,10 +313,4 @@ return array(
|
|||
$capabilities['google_pay'] && ! $gateways['google_pay'] // Enable Google Pay.
|
||||
);
|
||||
},
|
||||
'settings.rest.reset_dismissed_todos' => static function( ContainerInterface $container ): ResetDismissedTodosEndpoint {
|
||||
return new ResetDismissedTodosEndpoint();
|
||||
},
|
||||
'settings.rest.complete_onclick' => static function( ContainerInterface $container ): CompleteOnClickEndpoint {
|
||||
return new CompleteOnClickEndpoint();
|
||||
},
|
||||
);
|
||||
|
|
|
@ -64,9 +64,8 @@ class TodosDefinition {
|
|||
'action' => array(
|
||||
'type' => 'tab',
|
||||
'tab' => 'payment_methods',
|
||||
'section' => 'ppcp-fastlane',
|
||||
'modal' => 'ppcp-fastlane-gateway',
|
||||
'highlight' => 'ppcp-fastlane-gateway',
|
||||
'section' => 'ppcp-axo-gateway',
|
||||
'highlight' => 'ppcp-axo-gateway',
|
||||
),
|
||||
),
|
||||
'enable_credit_debit_cards' => array(
|
||||
|
|
|
@ -1,74 +1,93 @@
|
|||
<?php
|
||||
/**
|
||||
* PayPal Commerce Todos Model
|
||||
* Todos details class
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Settings\Data
|
||||
*/
|
||||
|
||||
declare( strict_types = 1 );
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Settings\Data;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Class TodosModel
|
||||
*
|
||||
* Handles the storage and retrieval of task completion states in WordPress options table.
|
||||
* Provides methods to get and update completion states with proper type casting.
|
||||
* Handles todos data persistence and state management.
|
||||
*/
|
||||
class TodosModel {
|
||||
/**
|
||||
* WordPress option name for storing the completion states.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected const OPTION_NAME = 'ppcp_todos';
|
||||
class TodosModel extends AbstractDataModel {
|
||||
|
||||
/**
|
||||
* Retrieves the formatted completion states from WordPress options.
|
||||
*
|
||||
* Loads the raw completion states from wp_options table and formats them into a
|
||||
* standardized array structure with proper type casting.
|
||||
*
|
||||
* @return array The formatted completion states array.
|
||||
* Option key for WordPress storage.
|
||||
*/
|
||||
public function get() : array {
|
||||
$completion_states = get_option( self::OPTION_NAME, array() );
|
||||
protected const OPTION_KEY = 'ppcp-settings';
|
||||
|
||||
return array_map(
|
||||
/**
|
||||
* Ensures the task completion states are boolean values.
|
||||
*
|
||||
* @param mixed $state value to sanitize, as stored in the DB.
|
||||
*/
|
||||
static fn( $state ) => (bool) $state,
|
||||
$completion_states
|
||||
/**
|
||||
* Returns the default structure for settings data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_defaults(): array {
|
||||
return array(
|
||||
'dismissedTodos' => array(),
|
||||
'completedOnClickTodos' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the completion states in WordPress options.
|
||||
* Gets the dismissed todos.
|
||||
*
|
||||
* Converts the provided data array and saves it to wp_options table.
|
||||
* Throws an exception if update fails.
|
||||
*
|
||||
* @param array $states Array of task IDs and their completion states.
|
||||
* @return void
|
||||
* @throws RuntimeException When the completion states update fails.
|
||||
* @return array
|
||||
*/
|
||||
public function update( array $states ) : void {
|
||||
$completion_states = array_map(
|
||||
static function ( $state ) {
|
||||
return (bool) $state;
|
||||
},
|
||||
$states
|
||||
public function get_dismissed_todos(): array {
|
||||
return $this->data['dismissedTodos'] ?? array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the completed onclick todos.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_completed_onclick_todos(): array {
|
||||
return $this->data['completedOnClickTodos'] ?? array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates dismissed todos.
|
||||
*
|
||||
* @param array $todo_ids Array of todo IDs to mark as dismissed.
|
||||
*/
|
||||
public function update_dismissed_todos( array $todo_ids ): void {
|
||||
$this->data['dismissedTodos'] = array_unique( $todo_ids );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates completed onclick todos.
|
||||
*
|
||||
* @param array $todo_ids Array of todo IDs to mark as completed.
|
||||
*/
|
||||
public function update_completed_onclick_todos( array $todo_ids ): void {
|
||||
$this->data['completedOnClickTodos'] = array_unique( $todo_ids );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets dismissed todos.
|
||||
*/
|
||||
public function reset_dismissed_todos(): void {
|
||||
$this->data['dismissedTodos'] = array();
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current todos data including dismissed and completed states.
|
||||
*
|
||||
* @return array The todos data array.
|
||||
*/
|
||||
public function get_todos_data(): array {
|
||||
return array(
|
||||
'dismissedTodos' => $this->get_dismissed_todos(),
|
||||
'completedOnClickTodos' => $this->get_completed_onclick_todos(),
|
||||
);
|
||||
|
||||
$result = update_option( self::OPTION_NAME, $completion_states );
|
||||
|
||||
if ( ! $result ) {
|
||||
throw new RuntimeException( 'Failed to update todo completion states' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace WooCommerce\PayPalCommerce\Settings\Endpoint;
|
|||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use WP_REST_Request;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\TodosModel;
|
||||
|
||||
/**
|
||||
* Class CompleteOnClickEndpoint
|
||||
|
@ -36,6 +37,22 @@ class CompleteOnClickEndpoint extends RestEndpoint {
|
|||
*/
|
||||
protected $rest_base = 'complete-onclick';
|
||||
|
||||
/**
|
||||
* The todos model instance.
|
||||
*
|
||||
* @var TodosModel
|
||||
*/
|
||||
protected TodosModel $todos;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param TodosModel $todos The todos model instance.
|
||||
*/
|
||||
public function __construct( TodosModel $todos ) {
|
||||
$this->todos = $todos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the routes for the complete-onclick endpoint.
|
||||
*
|
||||
|
@ -71,26 +88,22 @@ class CompleteOnClickEndpoint extends RestEndpoint {
|
|||
return $this->return_error( __( 'Todo ID is required.', 'woocommerce-paypal-payments' ) );
|
||||
}
|
||||
|
||||
$settings = get_option( 'ppcp-settings', array() );
|
||||
try {
|
||||
$todos_data = $this->todos->get_todos_data();
|
||||
$completed_todos = $todos_data['completedOnClickTodos'];
|
||||
|
||||
if ( ! isset( $settings['completedOnClickTodos'] ) ) {
|
||||
$settings['completedOnClickTodos'] = array();
|
||||
}
|
||||
|
||||
if ( ! in_array( $todo_id, $settings['completedOnClickTodos'], true ) ) {
|
||||
$settings['completedOnClickTodos'][] = $todo_id;
|
||||
$update_result = update_option( 'ppcp-settings', $settings );
|
||||
|
||||
if ( ! $update_result ) {
|
||||
return $this->return_error( __( 'Failed to mark todo as completed on click.', 'woocommerce-paypal-payments' ) );
|
||||
if ( ! in_array( $todo_id, $completed_todos, true ) ) {
|
||||
$this->todos->update_completed_onclick_todos( array_merge( $completed_todos, array( $todo_id ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->return_success(
|
||||
array(
|
||||
'message' => __( 'Todo marked as completed on click successfully.', 'woocommerce-paypal-payments' ),
|
||||
'todoId' => $todo_id,
|
||||
)
|
||||
);
|
||||
return $this->return_success(
|
||||
array(
|
||||
'message' => __( 'Todo marked as completed on click successfully.', 'woocommerce-paypal-payments' ),
|
||||
'todoId' => $todo_id,
|
||||
)
|
||||
);
|
||||
} catch ( \Exception $e ) {
|
||||
return $this->return_error( __( 'Failed to mark todo as completed on click.', 'woocommerce-paypal-payments' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace WooCommerce\PayPalCommerce\Settings\Endpoint;
|
|||
use WP_REST_Server;
|
||||
use WP_REST_Response;
|
||||
use WP_REST_Request;
|
||||
use WooCommerce\PayPalCommerce\Settings\Data\TodosModel;
|
||||
|
||||
/**
|
||||
* Class ResetDismissedTodosEndpoint
|
||||
|
@ -29,6 +30,22 @@ class ResetDismissedTodosEndpoint extends RestEndpoint {
|
|||
*/
|
||||
protected $rest_base = 'reset-dismissed-todos';
|
||||
|
||||
/**
|
||||
* The todos model instance.
|
||||
*
|
||||
* @var TodosModel
|
||||
*/
|
||||
protected TodosModel $todos;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param TodosModel $todos The todos model instance.
|
||||
*/
|
||||
public function __construct( TodosModel $todos ) {
|
||||
$this->todos = $todos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the REST API route for resetting todos.
|
||||
*/
|
||||
|
@ -54,23 +71,18 @@ class ResetDismissedTodosEndpoint extends RestEndpoint {
|
|||
* @return WP_REST_Response The response containing reset status.
|
||||
*/
|
||||
public function reset_dismissed_todos( WP_REST_Request $request ): WP_REST_Response {
|
||||
$settings = get_option( 'ppcp-settings', array() );
|
||||
try {
|
||||
$this->todos->reset_dismissed_todos();
|
||||
|
||||
$settings['dismissedTodos'] = array();
|
||||
|
||||
// Clear the completedOnClickTodos for testing purposes.
|
||||
// $settings['completedOnClickTodos'] = array();.
|
||||
|
||||
$update_result = update_option( 'ppcp-settings', $settings );
|
||||
|
||||
if ( ! $update_result ) {
|
||||
return $this->return_error( __( 'Failed to reset dismissed todos.', 'woocommerce-paypal-payments' ) );
|
||||
return $this->return_success(
|
||||
array(
|
||||
'message' => __( 'Dismissed todos reset successfully.', 'woocommerce-paypal-payments' ),
|
||||
)
|
||||
);
|
||||
} catch ( \Exception $e ) {
|
||||
return $this->return_error(
|
||||
__( 'Failed to reset dismissed todos.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
|
||||
return $this->return_success(
|
||||
array(
|
||||
'message' => __( 'Dismissed todos reset successfully.', 'woocommerce-paypal-payments' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/**
|
||||
* REST endpoint to manage the things to do items.
|
||||
*
|
||||
* Provides endpoints for retrieving, updating, and resetting todos
|
||||
* Provides endpoints for retrieving, updating, completing, resetting, and managing todos
|
||||
* via WP REST API routes.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Settings\Endpoint
|
||||
|
@ -75,10 +75,7 @@ class TodosRestEndpoint extends RestEndpoint {
|
|||
* Registers the REST API routes for todos management.
|
||||
*/
|
||||
public function register_routes(): void {
|
||||
/**
|
||||
* GET wc/v3/wc_paypal/todos
|
||||
* POST wc/v3/wc_paypal/todos
|
||||
*/
|
||||
// GET/POST /todos - Get todos list and update dismissed todos.
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base,
|
||||
|
@ -95,6 +92,28 @@ class TodosRestEndpoint extends RestEndpoint {
|
|||
),
|
||||
)
|
||||
);
|
||||
|
||||
// POST /todos/reset - Reset dismissed todos.
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . '/reset',
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => array( $this, 'reset_dismissed_todos' ),
|
||||
'permission_callback' => array( $this, 'check_permission' ),
|
||||
)
|
||||
);
|
||||
|
||||
// POST /todos/complete - Mark todo as completed on click.
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . '/complete',
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => array( $this, 'complete_onclick' ),
|
||||
'permission_callback' => array( $this, 'check_permission' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,9 +122,9 @@ class TodosRestEndpoint extends RestEndpoint {
|
|||
* @return WP_REST_Response The response containing todos data.
|
||||
*/
|
||||
public function get_todos(): WP_REST_Response {
|
||||
$settings = get_option( 'ppcp-settings', array() );
|
||||
$dismissed_ids = $settings['dismissedTodos'] ?? array();
|
||||
$completed_onclick_ids = $settings['completedOnClickTodos'] ?? array();
|
||||
$todos_data = $this->todos->get_todos_data();
|
||||
$dismissed_ids = $todos_data['dismissedTodos'];
|
||||
$completed_onclick_ids = $todos_data['completedOnClickTodos'];
|
||||
|
||||
$todos = array();
|
||||
foreach ( $this->todos_definition->get() as $id => $todo ) {
|
||||
|
@ -143,21 +162,73 @@ class TodosRestEndpoint extends RestEndpoint {
|
|||
* @return WP_REST_Response The response containing updated todos or error details.
|
||||
*/
|
||||
public function update_todos( WP_REST_Request $request ): WP_REST_Response {
|
||||
$data = $request->get_json_params();
|
||||
$settings = get_option( 'ppcp-settings', array() );
|
||||
$data = $request->get_json_params();
|
||||
|
||||
if ( isset( $data['dismissedTodos'] ) ) {
|
||||
$settings['dismissedTodos'] = array_unique(
|
||||
is_array( $data['dismissedTodos'] ) ? $data['dismissedTodos'] : array()
|
||||
);
|
||||
try {
|
||||
$dismissed_todos = is_array( $data['dismissedTodos'] ) ? $data['dismissedTodos'] : array();
|
||||
$this->todos->update_dismissed_todos( $dismissed_todos );
|
||||
|
||||
$update_result = update_option( 'ppcp-settings', $settings );
|
||||
|
||||
if ( $update_result ) {
|
||||
return $this->return_success( $settings );
|
||||
return $this->return_success( $this->todos->get_todos_data() );
|
||||
} catch ( \Exception $e ) {
|
||||
return $this->return_error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->return_success( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the completion of a todo item via click.
|
||||
*
|
||||
* @param WP_REST_Request $request The request instance.
|
||||
* @return WP_REST_Response The response containing completion status.
|
||||
*/
|
||||
public function complete_onclick( WP_REST_Request $request ): WP_REST_Response {
|
||||
$todo_id = $request->get_param( 'todoId' );
|
||||
|
||||
if ( ! $todo_id ) {
|
||||
return $this->return_error( __( 'Todo ID is required.', 'woocommerce-paypal-payments' ) );
|
||||
}
|
||||
|
||||
try {
|
||||
$todos_data = $this->todos->get_todos_data();
|
||||
$completed_todos = $todos_data['completedOnClickTodos'];
|
||||
|
||||
if ( ! in_array( $todo_id, $completed_todos, true ) ) {
|
||||
$this->todos->update_completed_onclick_todos( array_merge( $completed_todos, array( $todo_id ) ) );
|
||||
}
|
||||
|
||||
return $this->return_success(
|
||||
array(
|
||||
'message' => __( 'Todo marked as completed on click successfully.', 'woocommerce-paypal-payments' ),
|
||||
'todoId' => $todo_id,
|
||||
)
|
||||
);
|
||||
} catch ( \Exception $e ) {
|
||||
return $this->return_error( __( 'Failed to mark todo as completed on click.', 'woocommerce-paypal-payments' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all dismissed todos.
|
||||
*
|
||||
* @param WP_REST_Request $request The request instance.
|
||||
* @return WP_REST_Response The response containing reset status.
|
||||
*/
|
||||
public function reset_dismissed_todos( WP_REST_Request $request ): WP_REST_Response {
|
||||
try {
|
||||
$this->todos->reset_dismissed_todos();
|
||||
|
||||
return $this->return_success(
|
||||
array(
|
||||
'message' => __( 'Dismissed todos reset successfully.', 'woocommerce-paypal-payments' ),
|
||||
)
|
||||
);
|
||||
} catch ( \Exception $e ) {
|
||||
return $this->return_error(
|
||||
__( 'Failed to reset dismissed todos.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,10 +162,10 @@ class TodosEligibilityService {
|
|||
*/
|
||||
public function get_eligibility_checks(): array {
|
||||
return array(
|
||||
'enable_fastlane' => fn() => ! $this->is_fastlane_eligible,
|
||||
'enable_fastlane' => fn() => $this->is_fastlane_eligible,
|
||||
'enable_credit_debit_cards' => fn() => $this->is_card_payment_eligible,
|
||||
'enable_pay_later_messaging' => fn() => ! $this->is_pay_later_messaging_eligible,
|
||||
'add_pay_later_messaging' => fn() => $this->is_pay_later_messaging_eligible && ! $this->is_pay_later_messaging_ui_eligible,
|
||||
'enable_pay_later_messaging' => fn() => $this->is_pay_later_messaging_eligible,
|
||||
'add_pay_later_messaging' => fn() => $this->is_pay_later_messaging_eligible,
|
||||
'configure_paypal_subscription' => fn() => $this->is_subscription_eligible,
|
||||
'add_paypal_buttons' => fn() => $this->is_paypal_buttons_eligible,
|
||||
'register_domain_apple_pay' => fn() => $this->is_apple_pay_domain_eligible,
|
||||
|
|
|
@ -239,9 +239,7 @@ class SettingsModule implements ServiceModule, ExecutableModule {
|
|||
'settings' => $container->get( 'settings.rest.settings' ),
|
||||
'styling' => $container->get( 'settings.rest.styling' ),
|
||||
'todos' => $container->get( 'settings.rest.todos' ),
|
||||
'reset_dismissed_todos' => $container->get( 'settings.rest.reset_dismissed_todos' ),
|
||||
'pay_later_messaging' => $container->get( 'settings.rest.pay_later_messaging' ),
|
||||
'complete_onclick' => $container->get( 'settings.rest.complete_onclick' ),
|
||||
);
|
||||
|
||||
foreach ( $endpoints as $endpoint ) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue