counts(); return null === $counts ? array() : self::evaluate( $counts['active'], $counts['failing'], $counts['disabled'] ); } /** * Pure evaluation. * * @param int $active Active webhooks. * @param int $failing Active webhooks with recent delivery failures. * @param int $disabled Webhooks WooCommerce disabled after repeated failures. * @return Result[] */ public static function evaluate( int $active, int $failing, int $disabled ): array { if ( 0 === $active + $disabled ) { return array(); } $link = admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks' ); $label = __( 'View webhooks', 'keepwatch' ); if ( $disabled > 0 ) { return array( new Result( 'woocommerce.webhooks', Result::CRITICAL, /* translators: %d: number of webhooks */ sprintf( _n( '%d webhook was switched off after repeated failures', '%d webhooks were switched off after repeated failures', $disabled, 'keepwatch' ), $disabled ), __( 'WooCommerce stops a webhook after it fails several times in a row. The service it fed (for example shipping, accounting or an ERP) no longer receives orders. Fix the receiving address, then set the webhook to Active again.', 'keepwatch' ), $link, $label ), ); } if ( $failing > 0 ) { return array( new Result( 'woocommerce.webhooks', Result::RECOMMENDED, /* translators: %d: number of webhooks */ sprintf( _n( '%d webhook is failing to deliver', '%d webhooks are failing to deliver', $failing, 'keepwatch' ), $failing ), __( 'Recent deliveries failed. If it keeps failing, WooCommerce will switch the webhook off.', 'keepwatch' ), $link, $label ), ); } return array( new Result( 'woocommerce.webhooks', Result::GOOD, __( 'Webhooks deliver without errors', 'keepwatch' ) ) ); } /** * Webhook counts, or null if the table does not exist. * * @return array{active: int, failing: int, disabled: int}|null */ private function counts(): ?array { global $wpdb; $table = $wpdb->prefix . 'wc_webhooks'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- read-only counts, cached by the check schedule. if ( $table !== $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table ) ) ) ) { return null; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- see above. $row = $wpdb->get_row( $wpdb->prepare( 'SELECT SUM(status = %s) AS active, SUM(status = %s AND failure_count > 0) AS failing, SUM(status = %s AND failure_count > %d) AS disabled FROM %i', 'active', 'active', 'disabled', self::AUTO_DISABLE_FAILURES, $table ), ARRAY_A ); return is_array( $row ) ? array( 'active' => (int) $row['active'], 'failing' => (int) $row['failing'], 'disabled' => (int) $row['disabled'], ) : null; } }