Skip to content

Instantly share code, notes, and snippets.

@summersab
Last active February 14, 2021 01:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save summersab/b7ae1b41b3b466085cf24e293d4a92b4 to your computer and use it in GitHub Desktop.
Save summersab/b7ae1b41b3b466085cf24e293d4a92b4 to your computer and use it in GitHub Desktop.
Extension of the FoxyCart PHP SDK to include auto-debugging
<?php
require './vendor/autoload.php';
use Foxy\FoxyClient\FoxyClient;
class FoxyCustomClient extends FoxyClient {
private $parent_class_filename = "";
private $last_function_line = "";
private $last_function = "";
private $last_function_uri = "";
private $last_function_args = "";
private $last_function_file = "";
private $last_message = "";
public function __construct(\GuzzleHttp\Client $guzzle, array $config = array()) {
// If debugging is turned on and it is not being executed from the command line, echo the CSS for the collapsible
if (DEBUG == 1 && function_exists('getallheaders')) {
echo '<style>.debug input[type=checkbox]{display:none}.debug,.debug~*{font-family:monospace;margin:1em 0}label.debug.tree{display:block;padding:10px;border-left:1px solid #000;border-bottom:1px solid #000}pre.array{padding-left:30px}pre.array pre{margin-top:0;margin-bottom:0}pre.paren{margin-left:-30px}.toggle{float:left}.toggle.tree::before{content:"+\00a0"}input:checked+.toggle.tree:before{content:"-\00a0"}label.debug input+.toggle~*{display:none}label.debug input:checked+.toggle~*{display:block}label.debug.array p{text-decoration:underline;display:unset}.error,.error *{color:red!important;border-color:red!important}</style>';
}
$this->setParentClassFilename();
parent::__construct($guzzle, $config);
}
public function get($uri = "", $post = null) {
return $this->fcDebug(debug_backtrace(), __FUNCTION__, $uri, $post, parent::get($uri, $post));
}
public function post($uri = "", $post = null) {
return $this->fcDebug(debug_backtrace(), __FUNCTION__, $uri, $post, parent::post($uri, $post));
}
public function patch($uri = "", $post = null) {
return $this->fcDebug(debug_backtrace(), __FUNCTION__, $uri, $post, parent::patch($uri, $post));
}
public function put($uri = "", $post = null) {
return $this->fcDebug(debug_backtrace(), __FUNCTION__, $uri, $post, parent::put($uri, $post));
}
public function delete($uri = "", $post = null) {
return $this->fcDebug(debug_backtrace(), __FUNCTION__, $uri, $post, parent::delete($uri, $post));
}
public function options($uri = "", $post = null) {
return $this->fcDebug(debug_backtrace(), __FUNCTION__, $uri, $post, parent::options($uri, $post));
}
public function head($uri = "", $post = null) {
return $this->fcDebug(debug_backtrace(), __FUNCTION__, $uri, $post, parent::head($uri, $post));
}
private function setLastFunctionFile($backtrace) {
$this->last_function_file = $backtrace[0]['file'];
}
private function setLastFunctionLine($backtrace) {
$this->last_function_line = $backtrace[0]['line'];
}
private function setLastFunction($function) {
$this->last_function = strtoupper($function);
}
private function setLastFunctionUri($uri) {
$this->last_function_uri = $uri;
}
private function setLastFunctionArgs($post) {
$this->last_function_args = $post;
}
private function setLastMessage($result) {
$message = 'Success';
$statusCode = $this->getLastStatusCode();
if (isset($result['message']) || array_key_exists('message', $result)) {
$message = $result['message'];
}
else if ($statusCode < 200 || $statusCode >= 300) {
$message = 'Unknown error';
// I'm sure this seems awfully redundant, but it's the fastest and most accurate method according to:
// https://www.php.net/manual/en/function.array-key-exists.php#107786
if (isset($result['_embedded']) || array_key_exists('_embedded', $result) &&
isset($result['_embedded']['fx:errors']) || array_key_exists('fx:errors', $result['_embedded']) &&
isset($result['_embedded']['fx:errors'][0]) || array_key_exists('0', $result['_embedded']['fx:errors']) &&
isset($result['_embedded']['fx:errors'][0]['message']) || array_key_exists('message', $result['_embedded']['fx:errors'][0])
) {
$message = $result['_embedded']['fx:errors'][0]['message'];
}
}
$this->last_message = $message;
}
private function setParentClassFilename() {
$rc = new \ReflectionClass(get_parent_class($this));
$this->parent_class_filename = $rc->getFileName();
}
public function getLastFunctionFile() {
return $this->last_function_file;
}
public function getLastFunctionLine() {
return $this->last_function_line;
}
public function getLastFunction() {
return $this->last_function;
}
public function getLastFunctionUri() {
return $this->last_function_uri;
}
public function getLastFunctionArgs() {
return $this->last_function_args;
}
public function getLastMessage() {
return $this->last_message;
}
public function getParentClassFilename() {
return $this->parent_class_filename;
}
public function fcDebug($backtrace, $function, $uri, $post, $result) {
if ($uri == "" || $backtrace[0]['file'] == $this->getParentClassFilename()) {
return $result;
}
$this->setLastFunctionFile($backtrace);
$this->setLastFunctionLine($backtrace);
$this->setLastFunction($function);
$this->setLastFunctionUri($uri);
$this->setLastFunctionArgs($post);
$this->setLastMessage($result);
$statusCode = $this->getLastStatusCode();
$file = $this->getLastFunctionFile();
$line = $this->getLastFunctionLine();
$function = $this->getLastFunction();
$uri = $this->getLastFunctionUri();
$args = $this->getLastFunctionArgs();
$message = $this->getLastMessage();
$resourcePath = parse_url($uri)['path'];
$collection = end(explode('/', $resourcePath));
if (!ctype_digit($collection)) {
$result['_links']['first_resource'] = [
'href' => $result['_embedded']['fx:' . $collection]['0']['_links']['self']['href'],
'title' => 'First resource of this collection',
];
}
$html = "";
$error = "";
$expand = "";
if ($statusCode < 200 || $statusCode >= 300) {
$message = 'Error: ' . $message;
error_log($message . " " . $function . " " . $uri . " " . $file . ':' . $line);
$error = 'error';
}
if (DEBUG) {
if (EXPAND_MESSAGES) {
$expand = 'checked';
}
$htmlMsg = $message;
$htmlMsg .= '<br>' . $function . " " . $uri;
$htmlMsg .= '<br>' . $file . ':' . $line;
$details = 'Result:<br>' . $this->htmlizeArray($result);
if ($args !== null) {
$argsHtml = 'Args:<br>' . $this->htmlizeArray($args);
$details = $argsHtml . '<br><br>' . $details;
}
echo $this->htmlLog($htmlMsg, $details, $expand, $error);
}
return $result;
}
// I'm considering making htmlLog and htmlizeArray a separate class since they can be used agnostic of the Foxy PHP SDK
public function htmlLog($msg, $details = "", $expand = "", $error = "") {
$html = "";
if ($error) {
$error = 'error';
}
if ($details && $expand) {
$expand = 'checked';
}
else {
$expand = "";
}
if ($details) {
$html .= '<label class="debug tree ' . $error . '">' . $msg;
$html .= '<input type="checkbox" ' . $expand . '>';
$html .= '<div class="toggle"></div><pre>';
$html .= $details;
$html .= '</pre></label>';
}
else {
$html .= '<label class="debug tree ' . $error . '">' . $msg . '</label>';
}
return $html;
}
// I'm considering making htmlLog and htmlizeArray a separate class since they can be used agnostic of the Foxy PHP SDK
public function htmlizeArray($array, $expand = "") {
$html = "";
if ($expand !== null && EXPAND_ARRAYS) {
$expand = 'checked';
}
else {
$expand = "";
}
if (gettype($array) == 'array') {
$html .= '<label class="debug array"><p>Array</p>';
$html .= '<input type="checkbox" ' . $expand . '>';
$html .= '<div class="toggle"></div>';
$html .= '<pre class="array">';
$html .= '<pre class="paren">(</pre>';
// There's something wrong, here. I made a mess but couldn't make it work right.
foreach ($array as $key=>$el) {
$exp = $expand;
if ($key == '_links') {
$exp = null;
if (EXPAND_ARRAYS == 2) {
$exp = 'checked';
}
}
$html .= '<pre>[' . $key . '] => ' . $this->htmlizeArray($el, $exp) . '</pre>';
}
$html .= '<pre class="paren">)</pre>';
$html .= '</pre>';
$html .= '</label>';
}
else {
$html .= $array;
}
return $html;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment