Last active
February 14, 2021 01:25
-
-
Save summersab/b7ae1b41b3b466085cf24e293d4a92b4 to your computer and use it in GitHub Desktop.
Extension of the FoxyCart PHP SDK to include auto-debugging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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