/home/sylamedg/www/wp-content/plugins/woo-usps-simple-shipping/src/Debug.php
<?php
/** @noinspection PhpMultipleClassesDeclarationsInOneFile */
/** @noinspection MissingOrEmptyGroupStatementInspection */
declare(strict_types=1);
namespace Dgm\UspsSimple;
use Dgm\UspsSimple\Calc\Pair;
use Dgm\UspsSimple\Calc\Product;
use Dgm\UspsSimple\Calc\Request;
use Dgm\UspsSimple\Debug\XmlPrettyPrinter;
use WC_Product;
use WP_Error;
class Debug
{
public static function noop(): self
{
return new self(false);
}
public static function default(string $pluginFile): self
{
$self = new self(get_option('woocommerce_shipping_debug_mode', 'no') === 'yes');
if ($self->enabled) {
$self->pluginFile = $pluginFile;
add_action('woocommerce_before_checkout_form', [$self, '_show']);
add_action('woocommerce_before_cart', [$self, '_show']);
}
return $self;
}
public static function testing(): self
{
return new self(true);
}
private function __construct(bool $enabled) {
$this->enabled = $enabled;
if ($enabled) {
$this->data = new DebugData();
}
}
public function enabled(): bool
{
return $this->enabled;
}
public function recordSettings(array $props, array $settings): void
{
if (!$this->enabled) return;
$data = [];
unset($props['settings'], $props['form_fields']);
$data['props'] = $props;
$data['settings'] = $settings;
$this->data->settings = $data;
}
public function recordPackage($package): void
{
if (!$this->enabled) return;
if (is_array($package) && isset($package['contents']) && is_array($package['contents'])) {
foreach ($package['contents'] as &$line) {
$productData = null;
$wcProduct = $line['data'];
if ($wcProduct instanceof WC_Product) {
$p = Product::fromWcProduct($wcProduct);
$productData = [
'name' => $wcProduct->get_name(),
'slug' => $wcProduct->get_slug(),
'price' => $wcProduct->get_price(),
'regular_price' => $wcProduct->get_regular_price(),
'sale_price' => $wcProduct->get_sale_price(),
'weight' => $wcProduct->get_weight().' '.get_option('woocommerce_weight_unit'),
'weight_lbs' => $p->weight,
'dimensions' => join(' x ', [
$wcProduct->get_length(),
$wcProduct->get_width(),
$wcProduct->get_height(),
]).' '.get_option('woocommerce_dimension_unit'),
'dimensions_in' => join(' x ', [
$p->dim->length,
$p->dim->width,
$p->dim->height,
]),
];
}
$line['product'] = $productData;
unset($line['data']);
}
unset($line);
}
$this->data->package = $package;
}
/**
* @param Pair<string> $requests
*/
public function recordRequests(Pair $requests): void
{
if (!$this->enabled) return;
$this->data->requests = $requests;
}
public function recordTheRequest(Request $request): void
{
if (!$this->enabled) return;
$this->data->request = $request;
}
/**
* @param Pair<WP_Error|array|string> $responses
*/
public function recordResponses(Pair $responses): void
{
if (!$this->enabled) return;
$this->data->responses = $responses->map(function($r) {
if ($r instanceof WP_Error) {
return ['errors' => $r->get_error_messages()];
}
if (is_array($r)) {
unset($r['http_response']);
}
return $r;
});
}
public function recordCombinedResponse(string $response): void
{
if (!$this->enabled) return;
$this->data->combinedResponse = $response;
}
public function recordRates(array $shown): void
{
if (!$this->enabled) return;
$this->data->rates = $shown;
}
public function recordError(string $msg): void
{
if (!$this->enabled) return;
$this->data->error = $msg;
}
public function _show(): void
{
wp_enqueue_style('uspss-debug-css', plugins_url('public/debug/style.css', $this->pluginFile));
wp_enqueue_script('uspss-debug-js-clipboard', plugins_url('public/debug/clipboard.min.js', $this->pluginFile));
wp_enqueue_script('uspss-debug-js-main', plugins_url('public/debug/main.js', $this->pluginFile), [
'jquery',
'uspss-debug-js-clipboard',
]);
$props = get_object_vars($this);
unset($props['enabled']);
$rates = count($this->data->rates ?? []);
$notice =
"Found $rates USPS rates
<a class='uspss-debug-details'>details</a>
<a class='uspss-debug-copy'>copy</a>".
'<div class="uspss-debug-inner">
<pre>'.htmlspecialchars($this->data->format()).'</pre>
</div>';
?>
<div class="woocommerce-notices-wrapper">
<div class="woocommerce-message uspss-debug">
<?php echo $notice; ?>
</div>
</div>
<?php
}
public function format(): string
{
if (!$this->enabled) return '';
return $this->data->format();
}
/** @var bool */
private $enabled;
/** @var string */
private $pluginFile;
/** @var DebugData */
private $data;
}
class DebugData
{
/** @var string|null */
public $error;
/** @var array|null */
public $rates;
/** @var array */
public $settings;
/** @var mixed */
public $package;
/** @var Pair<string>|null */
public $requests;
/** @var Request|null */
public $request;
/** @var Pair<string|array>|null */
public $responses;
/** @var string */
public $combinedResponse;
/** @return string */
public function format(): string
{
$prettify = function($x) {
return XmlPrettyPrinter::tryPettyPrint($x);
};
$map = function($p, callable $f) {
if ($p instanceof Pair) {
return $p->map($f);
}
return $p;
};
$copy = clone($this);
$copy->requests = $map($copy->requests, $prettify);
$copy->responses = $map($copy->responses, function($r) use ($prettify) {
if (is_array($r)) {
if (isset($r['body'])) {
$r['body'] = $prettify($r['body']);
}
}
else if (is_string($r)) {
$r = $prettify($r);
}
return $r;
});
$copy->combinedResponse = $prettify($copy->combinedResponse);
$props = get_object_vars($copy);
// Suppress the 'var_export does not handle circular references' warning. We are ok
// with NULL's in place of such refs.
$export = @var_export($props, true);
return "`$export`";
}
}