Show webhooks

This commit is contained in:
Alex P 2021-09-16 13:48:20 +03:00
parent 0b029a9392
commit e2a7f6d8d9
12 changed files with 5132 additions and 7 deletions

View file

@ -9,6 +9,8 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Entity; namespace WooCommerce\PayPalCommerce\ApiClient\Entity;
use stdClass;
/** /**
* Class Webhook * Class Webhook
*/ */
@ -71,13 +73,38 @@ class Webhook {
/** /**
* Returns the event types. * Returns the event types.
* *
* @return array * @return stdClass[]
*/ */
public function event_types(): array { public function event_types(): array {
return $this->event_types; return $this->event_types;
} }
/**
* Returns the human-friendly names of the event types.
*
* @return string[]
*/
public function humanfriendly_event_names(): array {
return array_map(
function ( $event ): string {
return Webhook::get_humanfriendly_event_name( $event->name );
},
$this->event_types
);
}
/**
* Converts event names to more human-friendly form.
*
* @param string $name The event name like 'CHECKOUT.ORDER.APPROVED'.
* @return string
*/
public static function get_humanfriendly_event_name( string $name ): string {
return strtolower( str_replace( '.', ' ', $name ) );
}
/** /**
* Returns the object as array. * Returns the object as array.
* *

2
modules/ppcp-webhooks/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
node_modules
assets

View file

@ -9,4 +9,28 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Webhooks; namespace WooCommerce\PayPalCommerce\Webhooks;
return array(); use WooCommerce\PayPalCommerce\Onboarding\State;
use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
return array(
'wcgateway.settings.fields' => static function ( $container, array $fields ): array {
$status_page_fields = array(
'webhooks-list' => array(
'title' => __( 'Registered webhooks', 'woocommerce-paypal-payments' ),
'type' => 'ppcp-table',
'screens' => array(
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
),
'requirements' => array(),
'gateway' => WebhooksStatusPage::ID,
'classes' => array( 'ppcp-webhooks-table' ),
'value' => function () use ( $container ) : array {
return $container->get( 'webhook.status.registered-webhooks-data' );
},
),
);
return array_merge( $fields, $status_page_fields );
},
);

View file

@ -0,0 +1,23 @@
{
"name": "ppcp-wc-gateway",
"version": "1.0.0",
"license": "GPL-3.0-or-later",
"main": "resources/js/status-page.js",
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"babel-loader": "^8.1.0",
"cross-env": "^5.0.1",
"file-loader": "^4.2.0",
"node-sass": "^4.13.0",
"sass-loader": "^8.0.0",
"webpack": "^4.42.1",
"webpack-cli": "^3.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0"
},
"scripts": {
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
"watch": "cross-env BABEL_ENV=default NODE_ENV=production webpack --watch",
"dev": "cross-env BABEL_ENV=default webpack --watch"
}
}

View file

@ -0,0 +1,17 @@
.ppcp-webhooks-table {
.error {
color: red;
font-weight: bold;
}
table {
td {
padding: 0 10px 15px 0;
}
td:first-child {
vertical-align: top;
width: 450px;
}
}
}

View file

@ -0,0 +1,6 @@
document.addEventListener(
'DOMContentLoaded',
() => {
}
);

View file

@ -9,6 +9,10 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Webhooks; namespace WooCommerce\PayPalCommerce\Webhooks;
use Exception;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets;
use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderApproved; use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderApproved;
use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderCompleted; use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderCompleted;
use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted; use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted;
@ -18,7 +22,7 @@ use Psr\Container\ContainerInterface;
return array( return array(
'webhook.registrar' => function( $container ) : WebhookRegistrar { 'webhook.registrar' => function( $container ) : WebhookRegistrar {
$factory = $container->get( 'api.factory.webhook' ); $factory = $container->get( 'api.factory.webhook' );
$endpoint = $container->get( 'api.endpoint.webhook' ); $endpoint = $container->get( 'api.endpoint.webhook' );
$rest_endpoint = $container->get( 'webhook.endpoint.controller' ); $rest_endpoint = $container->get( 'webhook.endpoint.controller' );
@ -30,7 +34,7 @@ return array(
$logger $logger
); );
}, },
'webhook.endpoint.controller' => function( $container ) : IncomingWebhookEndpoint { 'webhook.endpoint.controller' => function( $container ) : IncomingWebhookEndpoint {
$webhook_endpoint = $container->get( 'api.endpoint.webhook' ); $webhook_endpoint = $container->get( 'api.endpoint.webhook' );
$webhook_factory = $container->get( 'api.factory.webhook' ); $webhook_factory = $container->get( 'api.factory.webhook' );
$handler = $container->get( 'webhook.endpoint.handler' ); $handler = $container->get( 'webhook.endpoint.handler' );
@ -45,7 +49,7 @@ return array(
... $handler ... $handler
); );
}, },
'webhook.endpoint.handler' => function( $container ) : array { 'webhook.endpoint.handler' => function( $container ) : array {
$logger = $container->get( 'woocommerce.logger.woocommerce' ); $logger = $container->get( 'woocommerce.logger.woocommerce' );
$prefix = $container->get( 'api.prefix' ); $prefix = $container->get( 'api.prefix' );
$order_endpoint = $container->get( 'api.endpoint.order' ); $order_endpoint = $container->get( 'api.endpoint.order' );
@ -57,4 +61,61 @@ return array(
new PaymentCaptureCompleted( $logger, $prefix ), new PaymentCaptureCompleted( $logger, $prefix ),
); );
}, },
'webhook.status.registered-webhooks' => function( $container ) : array {
$endpoint = $container->get( 'api.endpoint.webhook' );
assert( $endpoint instanceof WebhookEndpoint );
return $endpoint->list();
},
'webhook.status.registered-webhooks-data' => function( $container ) : array {
$empty_placeholder = __( 'No webhooks found.', 'woocommerce-paypal-payments' );
$webhooks = array();
try {
$webhooks = $container->get( 'webhook.status.registered-webhooks' );
} catch ( Exception $exception ) {
$empty_placeholder = sprintf(
'<span class="error">%s</span>',
__( 'Failed to load webhooks.', 'woocommerce-paypal-payments' )
);
}
return array(
'headers' => array(
__( 'URL', 'woocommerce-paypal-payments' ),
__( 'Tracked events', 'woocommerce-paypal-payments' ),
),
'data' => array_map(
function ( Webhook $webhook ): array {
return array(
esc_html( $webhook->url() ),
implode(
',<br/>',
array_map(
'esc_html',
$webhook->humanfriendly_event_names()
)
),
);
},
$webhooks
),
'empty_placeholder' => $empty_placeholder,
);
},
'webhook.status.assets' => function( $container ) : WebhooksStatusPageAssets {
return new WebhooksStatusPageAssets(
$container->get( 'webhook.module-url' )
);
},
'webhook.module-url' => static function ( $container ): string {
return plugins_url(
'/modules/ppcp-webhooks/',
dirname( __FILE__, 3 ) . '/woocommerce-paypal-payments.php'
);
},
); );

View file

@ -0,0 +1,84 @@
<?php
/**
* Register and configure assets for webhooks status page.
*
* @package WooCommerce\PayPalCommerce\Webhooks\Status\Assets
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
/**
* Class WebhooksStatusPageAssets
*/
class WebhooksStatusPageAssets {
/**
* The URL to the module.
*
* @var string
*/
private $module_url;
/**
* WebhooksStatusPageAssets constructor.
*
* @param string $module_url The URL to the module.
*/
public function __construct(
string $module_url
) {
$this->module_url = untrailingslashit( $module_url );
}
/**
* Registers the scripts and styles.
*
* @return void
*/
public function register(): void {
wp_register_style(
'ppcp-webhooks-status-page-style',
$this->module_url . '/assets/css/status-page.css',
array(),
1
);
wp_register_script(
'ppcp-webhooks-status-page',
$this->module_url . '/assets/js/status-page.js',
array(),
1,
true
);
wp_localize_script(
'ppcp-webhooks-status-page',
'PayPalCommerceGatewayWebhooksStatus',
$this->get_script_data()
);
}
/**
* Returns the data for the script.
*
* @return array
*/
public function get_script_data() {
return array();
}
/**
* Enqueues the necessary scripts.
*
* @return void
*/
public function enqueue(): void {
wp_enqueue_style( 'ppcp-webhooks-status-page-style' );
wp_enqueue_script( 'ppcp-webhooks-status-page' );
}
}

View file

@ -13,6 +13,8 @@ use Dhii\Container\ServiceProvider;
use Dhii\Modular\Module\ModuleInterface; use Dhii\Modular\Module\ModuleInterface;
use Interop\Container\ServiceProviderInterface; use Interop\Container\ServiceProviderInterface;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets;
use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage;
/** /**
* Class WebhookModule * Class WebhookModule
@ -79,6 +81,17 @@ class WebhookModule implements ModuleInterface {
$page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' ); $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' );
if ( WebhooksStatusPage::ID === $page_id ) { if ( WebhooksStatusPage::ID === $page_id ) {
$GLOBALS['hide_save_button'] = true; $GLOBALS['hide_save_button'] = true;
$asset_loader = $container->get( 'webhook.status.assets' );
assert( $asset_loader instanceof WebhooksStatusPageAssets );
add_action(
'init',
array( $asset_loader, 'register' )
);
add_action(
'admin_enqueue_scripts',
array( $asset_loader, 'enqueue' )
);
} }
} }

View file

@ -0,0 +1,36 @@
const path = require('path');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
devtool: 'sourcemap',
mode: isProduction ? 'production' : 'development',
target: 'web',
entry: {
'status-page': path.resolve('./resources/js/status-page.js'),
'status-page-style': path.resolve('./resources/css/status-page.scss'),
},
output: {
path: path.resolve(__dirname, 'assets/'),
filename: 'js/[name].js',
},
module: {
rules: [{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
{
loader: 'file-loader',
options: {
name: 'css/[name].css',
}
},
{loader:'sass-loader'}
]
}]
}
};

File diff suppressed because it is too large Load diff

View file

@ -8,10 +8,12 @@
"scripts": { "scripts": {
"install:modules:ppcp-button": "cd modules/ppcp-button && yarn install && cd -", "install:modules:ppcp-button": "cd modules/ppcp-button && yarn install && cd -",
"install:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn install && cd -", "install:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn install && cd -",
"install:modules": "yarn run install:modules:ppcp-button && yarn run install:modules:ppcp-wc-gateway", "install:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn install && cd -",
"install:modules": "yarn run install:modules:ppcp-button && yarn run install:modules:ppcp-wc-gateway && yarn run install:modules:ppcp-webhooks",
"build:modules:ppcp-button": "cd modules/ppcp-button && yarn run build && cd -", "build:modules:ppcp-button": "cd modules/ppcp-button && yarn run build && cd -",
"build:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn run build && cd -", "build:modules:ppcp-wc-gateway": "cd modules/ppcp-wc-gateway && yarn run build && cd -",
"build:modules": "yarn run build:modules:ppcp-button && yarn build:modules:ppcp-wc-gateway", "build:modules:ppcp-webhooks": "cd modules/ppcp-webhooks && yarn run build && cd -",
"build:modules": "yarn run build:modules:ppcp-button && yarn build:modules:ppcp-wc-gateway && yarn build:modules:ppcp-webhooks",
"build:dev": "yarn run install:modules && yarn run build:modules", "build:dev": "yarn run install:modules && yarn run build:modules",
"docker:build": "docker-compose build", "docker:build": "docker-compose build",