PageRenderTime 71ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/woocommerce/includes/admin/class-wc-admin-webhooks.php

https://gitlab.com/webkod3r/tripolis
PHP | 514 lines | 303 code | 97 blank | 114 comment | 65 complexity | 0483af76382caad4bfc1b9bf4d0e1d26 MD5 | raw file
  1. <?php
  2. /**
  3. * WooCommerce Admin Webhooks Class
  4. *
  5. * @author WooThemes
  6. * @category Admin
  7. * @package WooCommerce/Admin
  8. * @version 2.4.0
  9. */
  10. if ( ! defined( 'ABSPATH' ) ) {
  11. exit; // Exit if accessed directly
  12. }
  13. /**
  14. * WC_Admin_Webhooks.
  15. */
  16. class WC_Admin_Webhooks {
  17. /**
  18. * Initialize the webhooks admin actions.
  19. */
  20. public function __construct() {
  21. add_action( 'admin_init', array( $this, 'actions' ) );
  22. }
  23. /**
  24. * Check if is webhook settings page.
  25. *
  26. * @return bool
  27. */
  28. private function is_webhook_settings_page() {
  29. return isset( $_GET['page'] )
  30. && 'wc-settings' == $_GET['page']
  31. && isset( $_GET['tab'] )
  32. && 'api' == $_GET['tab']
  33. && isset( $_GET['section'] )
  34. && 'webhooks' == isset( $_GET['section'] );
  35. }
  36. /**
  37. * Updated the Webhook name.
  38. *
  39. * @param int $webhook_id
  40. */
  41. private function update_name( $webhook_id ) {
  42. global $wpdb;
  43. $name = ! empty( $_POST['webhook_name'] ) ? $_POST['webhook_name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) );
  44. $wpdb->update( $wpdb->posts, array( 'post_title' => $name ), array( 'ID' => $webhook_id ) );
  45. }
  46. /**
  47. * Updated the Webhook status.
  48. *
  49. * @param WC_Webhook $webhook
  50. */
  51. private function update_status( $webhook ) {
  52. $status = ! empty( $_POST['webhook_status'] ) ? wc_clean( $_POST['webhook_status'] ) : '';
  53. $webhook->update_status( $status );
  54. }
  55. /**
  56. * Updated the Webhook delivery URL.
  57. *
  58. * @param WC_Webhook $webhook
  59. */
  60. private function update_delivery_url( $webhook ) {
  61. $delivery_url = ! empty( $_POST['webhook_delivery_url'] ) ? $_POST['webhook_delivery_url'] : '';
  62. if ( wc_is_valid_url( $delivery_url ) ) {
  63. $webhook->set_delivery_url( $delivery_url );
  64. }
  65. }
  66. /**
  67. * Updated the Webhook secret.
  68. *
  69. * @param WC_Webhook $webhook
  70. */
  71. private function update_secret( $webhook ) {
  72. $secret = ! empty( $_POST['webhook_secret'] ) ? $_POST['webhook_secret'] : get_user_meta( get_current_user_id(), 'woocommerce_api_consumer_secret', true );
  73. $webhook->set_secret( $secret );
  74. }
  75. /**
  76. * Updated the Webhook topic.
  77. *
  78. * @param WC_Webhook $webhook
  79. */
  80. private function update_topic( $webhook ) {
  81. if ( ! empty( $_POST['webhook_topic'] ) ) {
  82. $resource = '';
  83. $event = '';
  84. switch ( $_POST['webhook_topic'] ) {
  85. case 'custom' :
  86. if ( ! empty( $_POST['webhook_custom_topic'] ) ) {
  87. list( $resource, $event ) = explode( '.', wc_clean( $_POST['webhook_custom_topic'] ) );
  88. }
  89. break;
  90. case 'action' :
  91. $resource = 'action';
  92. $event = ! empty( $_POST['webhook_action_event'] ) ? wc_clean( $_POST['webhook_action_event'] ) : '';
  93. break;
  94. default :
  95. list( $resource, $event ) = explode( '.', wc_clean( $_POST['webhook_topic'] ) );
  96. break;
  97. }
  98. $topic = $resource . '.' . $event;
  99. if ( wc_is_webhook_valid_topic( $topic ) ) {
  100. $webhook->set_topic( $topic );
  101. }
  102. }
  103. }
  104. /**
  105. * Save method.
  106. */
  107. private function save() {
  108. if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
  109. wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
  110. }
  111. $webhook_id = absint( $_POST['webhook_id'] );
  112. if ( ! current_user_can( 'edit_shop_webhook', $webhook_id ) ) {
  113. return;
  114. }
  115. $webhook = new WC_Webhook( $webhook_id );
  116. // Name
  117. $this->update_name( $webhook->id );
  118. // Status
  119. $this->update_status( $webhook );
  120. // Delivery URL
  121. $this->update_delivery_url( $webhook );
  122. // Secret
  123. $this->update_secret( $webhook );
  124. // Topic
  125. $this->update_topic( $webhook );
  126. // Run actions
  127. do_action( 'woocommerce_webhook_options_save', $webhook->id );
  128. delete_transient( 'woocommerce_webhook_ids' );
  129. // Ping the webhook at the first time that is activated
  130. $pending_delivery = get_post_meta( $webhook->id, '_webhook_pending_delivery', true );
  131. if ( isset( $_POST['webhook_status'] ) && 'active' === $_POST['webhook_status'] && $pending_delivery ) {
  132. $result = $webhook->deliver_ping();
  133. if ( is_wp_error( $result ) ) {
  134. // Redirect to webhook edit page to avoid settings save actions
  135. wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->id . '&error=' . urlencode( $result->get_error_message() ) ) );
  136. exit();
  137. }
  138. }
  139. // Redirect to webhook edit page to avoid settings save actions
  140. wp_safe_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->id . '&updated=1' ) );
  141. exit();
  142. }
  143. /**
  144. * Create Webhook.
  145. */
  146. private function create() {
  147. if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'create-webhook' ) ) {
  148. wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
  149. }
  150. if ( ! current_user_can( 'publish_shop_webhooks' ) ) {
  151. wp_die( __( 'You don\'t have permissions to create Webhooks!', 'woocommerce' ) );
  152. }
  153. $webhook_id = wp_insert_post( array(
  154. 'post_type' => 'shop_webhook',
  155. 'post_status' => 'pending',
  156. 'ping_status' => 'closed',
  157. 'post_author' => get_current_user_id(),
  158. 'post_password' => strlen( ( $password = uniqid( 'webhook_' ) ) ) > 20 ? substr( $password, 0, 20 ) : $password,
  159. 'post_title' => sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ),
  160. 'comment_status' => 'open'
  161. ) );
  162. if ( is_wp_error( $webhook_id ) ) {
  163. wp_die( $webhook_id->get_error_messages() );
  164. }
  165. update_post_meta( $webhook_id, '_webhook_pending_delivery', true );
  166. delete_transient( 'woocommerce_webhook_ids' );
  167. // Redirect to edit page
  168. wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook_id . '&created=1' ) );
  169. exit();
  170. }
  171. /**
  172. * Bulk trash/delete.
  173. *
  174. * @param array $webhooks
  175. * @param bool $delete
  176. */
  177. private function bulk_trash( $webhooks, $delete = false ) {
  178. foreach ( $webhooks as $webhook_id ) {
  179. if ( $delete ) {
  180. wp_delete_post( $webhook_id, true );
  181. } else {
  182. wp_trash_post( $webhook_id );
  183. }
  184. }
  185. $type = ! EMPTY_TRASH_DAYS || $delete ? 'deleted' : 'trashed';
  186. $qty = count( $webhooks );
  187. $status = isset( $_GET['status'] ) ? '&status=' . sanitize_text_field( $_GET['status'] ) : '';
  188. delete_transient( 'woocommerce_webhook_ids' );
  189. // Redirect to webhooks page
  190. wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks' . $status . '&' . $type . '=' . $qty ) );
  191. exit();
  192. }
  193. /**
  194. * Bulk untrash.
  195. *
  196. * @param array $webhooks
  197. */
  198. private function bulk_untrash( $webhooks ) {
  199. foreach ( $webhooks as $webhook_id ) {
  200. wp_untrash_post( $webhook_id );
  201. }
  202. $qty = count( $webhooks );
  203. delete_transient( 'woocommerce_webhook_ids' );
  204. // Redirect to webhooks page
  205. wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&status=trash&untrashed=' . $qty ) );
  206. exit();
  207. }
  208. /**
  209. * Bulk actions.
  210. */
  211. private function bulk_actions() {
  212. if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
  213. wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
  214. }
  215. if ( ! current_user_can( 'edit_shop_webhooks' ) ) {
  216. wp_die( __( 'You don\'t have permissions to edit Webhooks!', 'woocommerce' ) );
  217. }
  218. $webhooks = array_map( 'absint', (array) $_GET['webhook'] );
  219. switch ( $_GET['action'] ) {
  220. case 'trash' :
  221. $this->bulk_trash( $webhooks );
  222. break;
  223. case 'untrash' :
  224. $this->bulk_untrash( $webhooks );
  225. break;
  226. case 'delete' :
  227. $this->bulk_trash( $webhooks, true );
  228. break;
  229. default :
  230. break;
  231. }
  232. }
  233. /**
  234. * Empty Trash.
  235. */
  236. private function empty_trash() {
  237. if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'empty_trash' ) ) {
  238. wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
  239. }
  240. if ( ! current_user_can( 'delete_shop_webhooks' ) ) {
  241. wp_die( __( 'You don\'t have permissions to delete Webhooks!', 'woocommerce' ) );
  242. }
  243. $webhooks = get_posts( array(
  244. 'post_type' => 'shop_webhook',
  245. 'ignore_sticky_posts' => true,
  246. 'nopaging' => true,
  247. 'post_status' => 'trash',
  248. 'fields' => 'ids'
  249. ) );
  250. foreach ( $webhooks as $webhook_id ) {
  251. wp_delete_post( $webhook_id, true );
  252. }
  253. $qty = count( $webhooks );
  254. // Redirect to webhooks page
  255. wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&deleted=' . $qty ) );
  256. exit();
  257. }
  258. /**
  259. * Webhooks admin actions.
  260. */
  261. public function actions() {
  262. if ( $this->is_webhook_settings_page() ) {
  263. // Save
  264. if ( isset( $_POST['save'] ) && isset( $_POST['webhook_id'] ) ) {
  265. $this->save();
  266. }
  267. // Create
  268. if ( isset( $_GET['create-webhook'] ) ) {
  269. $this->create();
  270. }
  271. // Bulk actions
  272. if ( isset( $_GET['action'] ) && isset( $_GET['webhook'] ) ) {
  273. $this->bulk_actions();
  274. }
  275. // Empty trash
  276. if ( isset( $_GET['empty_trash'] ) ) {
  277. $this->empty_trash();
  278. }
  279. }
  280. }
  281. /**
  282. * Page output.
  283. */
  284. public static function page_output() {
  285. // Hide the save button
  286. $GLOBALS['hide_save_button'] = true;
  287. if ( isset( $_GET['edit-webhook'] ) ) {
  288. $webhook_id = absint( $_GET['edit-webhook'] );
  289. $webhook = new WC_Webhook( $webhook_id );
  290. if ( 'trash' != $webhook->post_data->post_status ) {
  291. include( 'settings/views/html-webhooks-edit.php' );
  292. return;
  293. }
  294. }
  295. self::table_list_output();
  296. }
  297. /**
  298. * Notices.
  299. */
  300. public static function notices() {
  301. if ( isset( $_GET['trashed'] ) ) {
  302. $trashed = absint( $_GET['trashed'] );
  303. WC_Admin_Settings::add_message( sprintf( _n( '1 webhook moved to the Trash.', '%d webhooks moved to the Trash.', $trashed, 'woocommerce' ), $trashed ) );
  304. }
  305. if ( isset( $_GET['untrashed'] ) ) {
  306. $untrashed = absint( $_GET['untrashed'] );
  307. WC_Admin_Settings::add_message( sprintf( _n( '1 webhook restored from the Trash.', '%d webhooks restored from the Trash.', $untrashed, 'woocommerce' ), $untrashed ) );
  308. }
  309. if ( isset( $_GET['deleted'] ) ) {
  310. $deleted = absint( $_GET['deleted'] );
  311. WC_Admin_Settings::add_message( sprintf( _n( '1 webhook permanently deleted.', '%d webhooks permanently deleted.', $deleted, 'woocommerce' ), $deleted ) );
  312. }
  313. if ( isset( $_GET['updated'] ) ) {
  314. WC_Admin_Settings::add_message( __( 'Webhook updated successfully.', 'woocommerce' ) );
  315. }
  316. if ( isset( $_GET['created'] ) ) {
  317. WC_Admin_Settings::add_message( __( 'Webhook created successfully.', 'woocommerce' ) );
  318. }
  319. if ( isset( $_GET['error'] ) ) {
  320. WC_Admin_Settings::add_error( wc_clean( $_GET['error'] ) );
  321. }
  322. }
  323. /**
  324. * Table list output.
  325. */
  326. private static function table_list_output() {
  327. echo '<h3>' . __( '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">' . __( 'Add Webhook', 'woocommerce' ) . '</a></h3>';
  328. $webhooks_table_list = new WC_Admin_Webhooks_Table_List();
  329. $webhooks_table_list->prepare_items();
  330. echo '<input type="hidden" name="page" value="wc-settings" />';
  331. echo '<input type="hidden" name="tab" value="api" />';
  332. echo '<input type="hidden" name="section" value="webhooks" />';
  333. $webhooks_table_list->views();
  334. $webhooks_table_list->search_box( __( 'Search Webhooks', 'woocommerce' ), 'webhook' );
  335. $webhooks_table_list->display();
  336. }
  337. /**
  338. * Logs output.
  339. *
  340. * @param WC_Webhook $webhook
  341. */
  342. public static function logs_output( $webhook ) {
  343. $current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1;
  344. $args = array(
  345. 'post_id' => $webhook->id,
  346. 'status' => 'approve',
  347. 'type' => 'webhook_delivery',
  348. 'number' => 10
  349. );
  350. if ( 1 < $current ) {
  351. $args['offset'] = ( $current - 1 ) * 10;
  352. }
  353. remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
  354. $logs = get_comments( $args );
  355. add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
  356. if ( $logs ) {
  357. include_once( 'settings/views/html-webhook-logs.php' );
  358. } else {
  359. echo '<p>' . __( 'This Webhook has no log yet.', 'woocommerce' ) . '</p>';
  360. }
  361. }
  362. /**
  363. * Get the webhook topic data.
  364. *
  365. * @return array
  366. */
  367. public static function get_topic_data( $webhook ) {
  368. $topic = $webhook->get_topic();
  369. $event = '';
  370. $resource = '';
  371. if ( $topic ) {
  372. list( $resource, $event ) = explode( '.', $topic );
  373. if ( 'action' === $resource ) {
  374. $topic = 'action';
  375. } else if ( ! in_array( $resource, array( 'coupon', 'customer', 'order', 'product' ) ) ) {
  376. $topic = 'custom';
  377. }
  378. }
  379. return array(
  380. 'topic' => $topic,
  381. 'event' => $event,
  382. 'resource' => $resource
  383. );
  384. }
  385. /**
  386. * Get the logs navigation.
  387. *
  388. * @param int $total
  389. *
  390. * @return string
  391. */
  392. public static function get_logs_navigation( $total, $webhook ) {
  393. $pages = ceil( $total / 10 );
  394. $current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1;
  395. $html = '<div class="webhook-logs-navigation">';
  396. $html .= '<p class="info" style="float: left;"><strong>';
  397. $html .= sprintf( '%s &ndash; Page %d of %d', _n( '1 item', sprintf( '%d items', $total ), $total, 'woocommerce' ), $current, $pages );
  398. $html .= '</strong></p>';
  399. if ( 1 < $pages ) {
  400. $html .= '<p class="tools" style="float: right;">';
  401. if ( 1 == $current ) {
  402. $html .= '<button class="button-primary" disabled="disabled">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</button> ';
  403. } else {
  404. $html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->id . '&log_page=' . ( $current - 1 ) ) . '#webhook-logs">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</a> ';
  405. }
  406. if ( $pages == $current ) {
  407. $html .= '<button class="button-primary" disabled="disabled">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</button>';
  408. } else {
  409. $html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->id . '&log_page=' . ( $current + 1 ) ) . '#webhook-logs">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</a>';
  410. }
  411. $html .= '</p>';
  412. }
  413. $html .= '<div class="clear"></div></div>';
  414. return $html;
  415. }
  416. }
  417. new WC_Admin_Webhooks();