woocommerce/includes/admin/class-wc-admin-webhooks.php

506 lines
16 KiB
PHP
Raw Normal View History

2015-01-09 17:42:01 +00:00
<?php
/**
2015-11-03 13:53:50 +00:00
* WooCommerce Admin Webhooks Class
2015-01-09 17:42:01 +00:00
*
* @author Automattic
2015-01-09 17:42:01 +00:00
* @category Admin
* @package WooCommerce/Admin
* @version 2.4.0
2015-01-09 17:42:01 +00:00
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
2015-01-09 17:42:01 +00:00
}
/**
* WC_Admin_Webhooks.
2015-01-09 17:42:01 +00:00
*/
class WC_Admin_Webhooks {
/**
* Initialize the webhooks admin actions.
2015-01-09 17:42:01 +00:00
*/
public function __construct() {
add_action( 'woocommerce_save_settings_api_webhooks', array( $this, 'allow_save_settings' ) );
2015-01-10 00:08:45 +00:00
add_action( 'admin_init', array( $this, 'actions' ) );
}
/**
* Check if should allow save settings.
* This prevents "Your settings have been saved." notices on the table list.
*
* @param bool $allow If allow save settings.
* @return bool
*/
public function allow_save_settings( $allow ) {
if ( ! isset( $_GET['edit-webhook'] ) ) {// WPCS: input var okay, CSRF ok.
return false;
}
return $allow;
}
2015-01-10 00:08:45 +00:00
/**
* Check if is webhook settings page.
2015-01-10 00:08:45 +00:00
*
* @return bool
*/
2015-01-10 00:25:04 +00:00
private function is_webhook_settings_page() {
2017-11-07 18:23:26 +00:00
return isset( $_GET['page'], $_GET['tab'], $_GET['section'] ) && 'wc-settings' === $_GET['page'] && 'api' === $_GET['tab'] && 'webhooks' === $_GET['section']; // WPCS: input var okay, CSRF ok.
2015-01-09 17:42:01 +00:00
}
/**
* Save method.
2015-01-09 17:42:01 +00:00
*/
private function save() {
check_admin_referer( 'woocommerce-settings' );
2015-01-09 17:42:01 +00:00
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_die( esc_html__( 'You do not have permission to update Webhooks', 'woocommerce' ) );
}
2015-01-09 17:42:01 +00:00
2017-11-07 18:23:26 +00:00
$webhook_id = isset( $_POST['webhook_id'] ) ? absint( $_POST['webhook_id'] ) : 0; // WPCS: input var okay, CSRF ok.
$webhook = new WC_Webhook( $webhook_id );
2015-01-09 17:42:01 +00:00
// Name.
2017-11-07 18:23:26 +00:00
if ( ! empty( $_POST['webhook_name'] ) ) { // WPCS: input var okay, CSRF ok.
$name = sanitize_text_field( wp_unslash( $_POST['webhook_name'] ) ); // WPCS: input var okay, CSRF ok.
} else {
$name = sprintf(
/* translators: %s: date */
__( 'Webhook created on %s', 'woocommerce' ),
// @codingStandardsIgnoreStart
strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) )
// @codingStandardsIgnoreEnd
);
}
$webhook->set_name( $name );
// Status.
2017-11-07 18:23:26 +00:00
$webhook->set_status( ! empty( $_POST['webhook_status'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_status'] ) ) : 'disabled' ); // WPCS: input var okay, CSRF ok.
// Delivery URL.
2017-11-07 18:23:26 +00:00
$delivery_url = ! empty( $_POST['webhook_delivery_url'] ) ? esc_url_raw( wp_unslash( $_POST['webhook_delivery_url'] ) ) : ''; // WPCS: input var okay, CSRF ok.
2015-01-09 17:42:01 +00:00
if ( wc_is_valid_url( $delivery_url ) ) {
$webhook->set_delivery_url( $delivery_url );
}
// Secret.
2017-11-07 18:23:26 +00:00
$secret = ! empty( $_POST['webhook_secret'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_secret'] ) ) : wp_generate_password( 50, true, true ); // WPCS: input var okay, CSRF ok.
2015-01-09 17:42:01 +00:00
$webhook->set_secret( $secret );
// Topic.
2017-11-07 18:23:26 +00:00
if ( ! empty( $_POST['webhook_topic'] ) ) { // WPCS: input var okay, CSRF ok.
$resource = '';
$event = '';
2017-11-07 18:23:26 +00:00
switch ( $_POST['webhook_topic'] ) { // WPCS: input var okay, CSRF ok.
case 'custom':
if ( ! empty( $_POST['webhook_custom_topic'] ) ) { // WPCS: input var okay, CSRF ok.
list( $resource, $event ) = explode( '.', sanitize_text_field( wp_unslash( $_POST['webhook_custom_topic'] ) ) ); // WPCS: input var okay, CSRF ok.
}
break;
2017-11-07 18:23:26 +00:00
case 'action':
$resource = 'action';
2017-11-07 18:23:26 +00:00
$event = ! empty( $_POST['webhook_action_event'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_action_event'] ) ) : ''; // WPCS: input var okay, CSRF ok.
break;
2017-11-07 18:23:26 +00:00
default:
list( $resource, $event ) = explode( '.', sanitize_text_field( wp_unslash( $_POST['webhook_topic'] ) ) ); // WPCS: input var okay, CSRF ok.
break;
2015-01-09 17:42:01 +00:00
}
$topic = $resource . '.' . $event;
if ( wc_is_webhook_valid_topic( $topic ) ) {
$webhook->set_topic( $topic );
}
}
2016-11-22 23:58:36 +00:00
// API version.
2017-11-07 18:23:26 +00:00
$webhook->set_api_version( ! empty( $_POST['webhook_api_version'] ) ? sanitize_text_field( wp_unslash( $_POST['webhook_api_version'] ) ) : 'wp_api_v2' ); // WPCS: input var okay, CSRF ok.
$webhook->save();
// Run actions.
do_action( 'woocommerce_webhook_options_save', $webhook->get_id() );
// Ping the webhook at the first time that is activated.
2017-11-07 18:23:26 +00:00
if ( isset( $_POST['webhook_status'] ) && 'active' === $_POST['webhook_status'] && $webhook->get_pending_delivery() ) { // WPCS: input var okay, CSRF ok.
$result = $webhook->deliver_ping();
if ( is_wp_error( $result ) ) {
// Redirect to webhook edit page to avoid settings save actions.
2017-11-07 18:23:26 +00:00
wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->get_id() . '&error=' . rawurlencode( $result->get_error_message() ) ) );
exit();
}
}
// Redirect to webhook edit page to avoid settings save actions.
wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->get_id() . '&updated=1' ) );
2015-01-10 00:08:45 +00:00
exit();
}
2015-01-09 17:42:01 +00:00
2015-01-10 00:08:45 +00:00
/**
* Create Webhook.
2015-01-10 00:08:45 +00:00
*/
private function create() {
check_admin_referer( 'create-webhook' );
2015-05-18 19:01:51 +00:00
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_die( esc_html__( 'You do not have permission to create Webhooks', 'woocommerce' ) );
2015-01-09 17:42:01 +00:00
}
2015-01-10 00:08:45 +00:00
$webhook = new WC_Webhook();
$webhook->set_status( 'disabled' );
$webhook->set_name( sprintf(
2016-10-29 10:16:03 +00:00
/* translators: %s: date */
__( 'Webhook created on %s', 'woocommerce' ),
// @codingStandardsIgnoreStart
strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) )
2016-09-01 20:50:14 +00:00
// @codingStandardsIgnoreEnd
);
$webhook->set_pending_delivery( true );
$webhook->set_api_version( 'wp_api_v2' );
$webhook->set_secret( wp_generate_password( 50, true, true ) );
$webhook->save();
2015-01-10 00:08:45 +00:00
// Redirect to edit page.
2017-11-07 18:23:26 +00:00
wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->get_id() . '&created=1' ) );
2015-01-10 00:08:45 +00:00
exit();
2015-01-09 17:42:01 +00:00
}
/**
* Bulk trash/delete.
2015-01-10 00:08:45 +00:00
*
* @param array $webhooks List of webhooks IDs.
* @param bool $delete If should delete or trash.
*/
2015-01-10 00:08:45 +00:00
private function bulk_trash( $webhooks, $delete = false ) {
foreach ( $webhooks as $webhook_id ) {
if ( $delete ) {
wp_delete_post( $webhook_id, true );
} else {
wp_trash_post( $webhook_id );
}
2015-01-10 00:08:45 +00:00
}
$type = ! EMPTY_TRASH_DAYS || $delete ? 'deleted' : 'trashed';
$qty = count( $webhooks );
2017-11-07 18:23:26 +00:00
$status = isset( $_GET['status'] ) ? '&status=' . sanitize_text_field( wp_unslash( $_GET['status'] ) ) : ''; // WPCS: input var okay, CSRF ok.
2015-05-18 19:01:51 +00:00
delete_transient( 'woocommerce_webhook_ids' );
// Redirect to webhooks page.
2017-11-07 18:23:26 +00:00
wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks' . $status . '&' . $type . '=' . $qty ) );
2015-01-10 00:08:45 +00:00
exit();
}
/**
* Bulk untrash.
2015-01-10 00:08:45 +00:00
*
* @param array $webhooks List of webhooks IDs.
2015-01-10 00:08:45 +00:00
*/
private function bulk_untrash( $webhooks ) {
foreach ( $webhooks as $webhook_id ) {
wp_untrash_post( $webhook_id );
}
$qty = count( $webhooks );
2015-05-18 19:01:51 +00:00
delete_transient( 'woocommerce_webhook_ids' );
// Redirect to webhooks page.
2017-11-07 18:23:26 +00:00
wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&status=trash&untrashed=' . $qty ) );
2015-01-10 00:08:45 +00:00
exit();
}
/**
* Bulk actions.
2015-01-10 00:08:45 +00:00
*/
private function bulk_actions() {
check_admin_referer( 'woocommerce-settings' );
2015-05-18 19:01:51 +00:00
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_die( esc_html__( 'You do not have permission to edit Webhooks', 'woocommerce' ) );
2015-01-10 00:08:45 +00:00
}
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['action'] ) ) { // WPCS: input var okay, CSRF ok.
$webhooks = isset( $_GET['webhook'] ) ? array_map( 'absint', (array) $_GET['webhook'] ) : array(); // WPCS: input var okay, CSRF ok.
2017-11-07 18:23:26 +00:00
switch ( sanitize_text_field( wp_unslash( $_GET['action'] ) ) ) { // WPCS: input var okay, CSRF ok.
case 'trash':
$this->bulk_trash( $webhooks );
break;
2017-11-07 18:23:26 +00:00
case 'untrash':
$this->bulk_untrash( $webhooks );
break;
2017-11-07 18:23:26 +00:00
case 'delete':
$this->bulk_trash( $webhooks, true );
break;
2017-11-07 18:23:26 +00:00
default:
break;
}
2015-01-10 00:08:45 +00:00
}
}
2015-01-10 01:03:22 +00:00
/**
* Empty Trash.
2015-01-10 01:03:22 +00:00
*/
private function empty_trash() {
check_admin_referer( 'empty_trash' );
2015-05-18 19:01:51 +00:00
if ( ! current_user_can( 'manage_woocommerce' ) ) {
wp_die( esc_html__( 'You do not have permission to delete Webhooks', 'woocommerce' ) );
2015-01-10 01:03:22 +00:00
}
2017-11-07 18:23:26 +00:00
// @codingStandardsIgnoreStart
2015-01-10 01:03:22 +00:00
$webhooks = get_posts( array(
'post_type' => 'shop_webhook',
'ignore_sticky_posts' => true,
'nopaging' => true,
'post_status' => 'trash',
'fields' => 'ids',
2015-01-10 01:03:22 +00:00
) );
2017-11-07 18:23:26 +00:00
// @codingStandardsIgnoreEnd
2015-01-10 01:03:22 +00:00
foreach ( $webhooks as $webhook_id ) {
wp_delete_post( $webhook_id, true );
}
$qty = count( $webhooks );
// Redirect to webhooks page.
2017-11-07 18:23:26 +00:00
wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&deleted=' . $qty ) );
2015-01-10 01:03:22 +00:00
exit();
}
2015-01-10 00:08:45 +00:00
/**
* Webhooks admin actions.
2015-01-10 00:08:45 +00:00
*/
public function actions() {
2015-01-10 00:25:04 +00:00
if ( $this->is_webhook_settings_page() ) {
// Save.
2017-11-07 18:23:26 +00:00
if ( isset( $_POST['save'] ) && isset( $_POST['webhook_id'] ) ) { // WPCS: input var okay, CSRF ok.
2015-01-10 00:08:45 +00:00
$this->save();
}
// Create.
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['create-webhook'] ) ) { // WPCS: input var okay, CSRF ok.
2015-01-10 00:08:45 +00:00
$this->create();
}
// Bulk actions.
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['action'] ) && isset( $_GET['webhook'] ) ) { // WPCS: input var okay, CSRF ok.
2015-01-10 00:08:45 +00:00
$this->bulk_actions();
}
2015-01-10 01:03:22 +00:00
// Empty trash.
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['empty_trash'] ) ) { // WPCS: input var okay, CSRF ok.
2015-01-10 01:03:22 +00:00
$this->empty_trash();
}
}
}
/**
* Page output.
*/
2015-05-16 02:03:24 +00:00
public static function page_output() {
// Hide the save button.
$GLOBALS['hide_save_button'] = true;
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['edit-webhook'] ) ) { // WPCS: input var okay, CSRF ok.
$webhook_id = absint( $_GET['edit-webhook'] ); // WPCS: input var okay, CSRF ok.
$webhook = new WC_Webhook( $webhook_id );
2017-11-07 18:23:26 +00:00
if ( 'trash' !== $webhook->get_status() ) {
2015-05-16 02:03:24 +00:00
include( 'settings/views/html-webhooks-edit.php' );
return;
}
}
self::table_list_output();
}
/**
2015-05-16 02:03:24 +00:00
* Notices.
*/
2015-05-16 02:03:24 +00:00
public static function notices() {
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['trashed'] ) ) { // WPCS: input var okay, CSRF ok.
$trashed = absint( $_GET['trashed'] ); // WPCS: input var okay, CSRF ok.
2016-10-29 10:16:03 +00:00
/* translators: %d: count */
WC_Admin_Settings::add_message( sprintf( _n( '%d webhook moved to the Trash.', '%d webhooks moved to the Trash.', $trashed, 'woocommerce' ), $trashed ) );
}
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['untrashed'] ) ) { // WPCS: input var okay, CSRF ok.
$untrashed = absint( $_GET['untrashed'] ); // WPCS: input var okay, CSRF ok.
2016-10-29 10:16:03 +00:00
/* translators: %d: count */
WC_Admin_Settings::add_message( sprintf( _n( '%d webhook restored from the Trash.', '%d webhooks restored from the Trash.', $untrashed, 'woocommerce' ), $untrashed ) );
}
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['deleted'] ) ) { // WPCS: input var okay, CSRF ok.
$deleted = absint( $_GET['deleted'] ); // WPCS: input var okay, CSRF ok.
2016-10-29 10:16:03 +00:00
/* translators: %d: count */
WC_Admin_Settings::add_message( sprintf( _n( '%d webhook permanently deleted.', '%d webhooks permanently deleted.', $deleted, 'woocommerce' ), $deleted ) );
}
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['updated'] ) ) { // WPCS: input var okay, CSRF ok.
WC_Admin_Settings::add_message( __( 'Webhook updated successfully.', 'woocommerce' ) );
}
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['created'] ) ) { // WPCS: input var okay, CSRF ok.
WC_Admin_Settings::add_message( __( 'Webhook created successfully.', 'woocommerce' ) );
}
2017-11-07 18:23:26 +00:00
if ( isset( $_GET['error'] ) ) { // WPCS: input var okay, CSRF ok.
WC_Admin_Settings::add_error( sanitize_text_field( wp_unslash( $_GET['error'] ) ) ); // WPCS: input var okay, CSRF ok.
}
}
/**
* Table list output.
*/
2015-05-16 02:03:24 +00:00
private static function table_list_output() {
echo '<h2>' . esc_html__( 'Webhooks', 'woocommerce' ) . ' <a href="' . esc_url( wp_nonce_url( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&create-webhook=1' ), 'create-webhook' ) ) . '" class="add-new-h2">' . esc_html__( 'Add webhook', 'woocommerce' ) . '</a></h2>';
// Get the webhooks count.
$data_store = WC_Data_Store::load( 'webhook' );
$count = count( $data_store->get_webhooks_ids() );
if ( 0 < $count ) {
$webhooks_table_list = new WC_Admin_Webhooks_Table_List();
$webhooks_table_list->prepare_items();
echo '<input type="hidden" name="page" value="wc-settings" />';
echo '<input type="hidden" name="tab" value="api" />';
echo '<input type="hidden" name="section" value="webhooks" />';
$webhooks_table_list->views();
$webhooks_table_list->search_box( __( 'Search webhooks', 'woocommerce' ), 'webhook' );
$webhooks_table_list->display();
} else {
2017-04-27 11:23:16 +00:00
echo '<div class="woocommerce-BlankState woocommerce-BlankState--webhooks">';
?>
<h2 class="woocommerce-BlankState-message"><?php esc_html_e( 'Webhooks are event notifications sent to URLs of your choice. They can be used to integrate with third-party services which support them.', 'woocommerce' ); ?></h2>
<a class="woocommerce-BlankState-cta button-primary button" href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&create-webhook=1' ), 'create-webhook' ) ); ?>"><?php esc_html_e( 'Create a new webhook', 'woocommerce' ); ?></a>
2017-11-07 18:23:26 +00:00
<?php
echo '<style type="text/css">#posts-filter .wp-list-table, #posts-filter .tablenav.top, .tablenav.bottom .actions { display: none; } </style></div>';
}
}
/**
* Logs output.
*
* @param WC_Webhook $webhook Webhook instance.
*/
public static function logs_output( $webhook ) {
2017-11-07 18:23:26 +00:00
$current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1; // WPCS: input var okay, CSRF ok.
$args = array(
'post_id' => $webhook->get_id(),
'status' => 'approve',
'type' => 'webhook_delivery',
'number' => 10,
);
if ( 1 < $current ) {
$args['offset'] = ( $current - 1 ) * 10;
}
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
$logs = get_comments( $args );
add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
if ( $logs ) {
include_once( dirname( __FILE__ ) . '/settings/views/html-webhook-logs.php' );
} else {
echo '<p>' . esc_html__( 'This Webhook has no log yet.', 'woocommerce' ) . '</p>';
}
}
/**
* Get the webhook topic data.
*
* @param WC_Webhook $webhook Webhook instance.
*
* @return array
*/
public static function get_topic_data( $webhook ) {
$topic = $webhook->get_topic();
$event = '';
$resource = '';
if ( $topic ) {
list( $resource, $event ) = explode( '.', $topic );
if ( 'action' === $resource ) {
$topic = 'action';
2017-11-07 18:23:26 +00:00
} elseif ( ! in_array( $resource, array( 'coupon', 'customer', 'order', 'product' ), true ) ) {
$topic = 'custom';
}
}
return array(
'topic' => $topic,
'event' => $event,
'resource' => $resource,
);
}
/**
* Get the logs navigation.
*
* @param int $total Number of logs.
* @param WC_Webhook $webhook Webhook instance.
*
* @return string
*/
public static function get_logs_navigation( $total, $webhook ) {
$pages = ceil( $total / 10 );
2017-11-07 18:23:26 +00:00
$current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1; // WPCS: input var okay, CSRF ok.
$html = '<div class="webhook-logs-navigation">';
$html .= '<p class="info" style="float: left;"><strong>';
$html .= sprintf(
2017-11-07 18:23:26 +00:00
/* translators: 1: items count (i.e. 8 items) 2: current page 3: total pages */
esc_html__( '%1$s &ndash; Page %2$d of %3$d', 'woocommerce' ),
/* translators: %d: items count */
esc_html( sprintf( _n( '%d item', '%d items', $total, 'woocommerce' ), $total ) ),
$current,
$pages
);
$html .= '</strong></p>';
if ( 1 < $pages ) {
$html .= '<p class="tools" style="float: right;">';
2017-11-07 18:23:26 +00:00
if ( 1 === $current ) {
$html .= '<button class="button-primary" disabled="disabled">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</button> ';
} else {
$html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->get_id() . '&log_page=' . ( $current - 1 ) ) . '#webhook-logs">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</a> ';
}
2017-11-07 18:23:26 +00:00
if ( $pages === $current ) {
$html .= '<button class="button-primary" disabled="disabled">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</button>';
} else {
$html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->get_id() . '&log_page=' . ( $current + 1 ) ) . '#webhook-logs">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</a>';
}
$html .= '</p>';
}
$html .= '<div class="clear"></div></div>';
return $html;
}
2015-01-09 17:42:01 +00:00
}
new WC_Admin_Webhooks();