Current File : /home/kelaby89/jrncommunityhousing.charity/wp-content/plugins/give/src/Log/Log.php |
<?php
namespace Give\Log;
use Exception;
use Give\Log\Helpers\Environment;
use Give\Log\ValueObjects\LogType;
/**
* Class Log
*
* The static facade intended to be the primary way of logging within GiveWP to make life easier.
*
* @since 2.21.0 Use array_diff_key to filter context data to prevent php warning with multi-dimension array
* @since 2.20.0 add sensitive information redaction; store context as arrays for JSON serialization
* @since 2.19.6 added debug
* @since 2.10.0
*
* @note There are two special keywords used in the context that are representing category and source.
* The default value for the Category is "Core" and for the source is "Give Core"
* If you want to change the category and/or source, you should provide them as context attributes.
* Source and category attributes should be written lowercase.
*
* @example
*
* Log::error( 'Error message', [
* 'category' => 'Payment',
* 'source' => 'Stripe add-on'
* ] );
*
* @note Use as many contexts attributes as you need. The more the better.
*
* @example
*
* Log::error( 'Error message', [
* 'category' => 'Payment',
* 'source' => 'Stripe add-on',
* 'donation_id' => $donationId,
* 'donor_id' => $donorId
* ] );
*
* @note You can use an array or object as a context attribute value.
*
* @example
*
* try {
* something();
* } catch ( Exception $exception ) {
* Log::error( 'Something went wrong', [
* 'exception' => $exception,
* 'additional_info' => [
* 'donation_id' => $donationId
* ]
* ] );
* }
*
*
* @method static void error(string $message, array $context = [])
* @method static void warning(string $message, array $context = [])
* @method static void notice(string $message, array $context = [])
* @method static void success(string $message, array $context = [])
* @method static void info(string $message, array $context = [])
* @method static void http(string $message, array $context = [])
* @method static void spam(string $message, array $context = [])
* @method static void debug(string $message, array $context = [])
*/
class Log
{
public function __call($name, $arguments)
{
list ($message, $context) = array_pad($arguments, 2, null);
if (is_array($context)) {
$context = $this->serializeAndRedactContext($context);
// Default fields
$data = array_filter(
$context,
function ($key) {
return array_key_exists($key, LogFactory::getDefaults());
},
ARRAY_FILTER_USE_KEY
);
// Additional context
$data['context'] = array_diff_key(
$context,
$data
);
}
// Set message
if (!is_null($message)) {
$data['message'] = $message;
}
// Set type
$data['type'] = $name;
try {
$log = LogFactory::makeFromArray($data);
$log->save();
return $log;
} catch (Exception $exception) {
error_log($exception->getMessage());
}
}
/**
* Takes the context array, serializes it, and redacts sensitive data.
*
* @since 2.20.0
*/
private function serializeAndRedactContext(array $context): array
{
$redactedData = [];
foreach ($context as $key => $value) {
foreach (self::getRedactionList() as $redaction) {
if (stripos($key, $redaction) !== false) {
$redactedData[$key] = '[[redacted]]';
continue 2;
}
}
if (is_array($value)) {
$value = $this->serializeAndRedactContext($value);
} elseif (is_object($value)) {
$value = $this->serializeAndRedactContext(
array_merge(
['Object Class' => get_class($value)],
(array)$value
)
);
}
$redactedData[$key] = $value;
}
return $redactedData;
}
/**
* Static helper for calling the logger methods
*
* @since 2.19.6 added conditional for logging debug()
* @since 2.18.0 - always log errors, warnings & only log all if WP_DEBUG_LOG is enabled
* @since 2.11.1
*
* @param array $arguments
*
* @param string $name
*/
public static function __callStatic($name, $arguments)
{
/** @var Log $logger */
$logger = give(__CLASS__);
if ($name !== LogType::DEBUG && (in_array($name, ['error', 'warning']) || Environment::isWPDebugLogEnabled())) {
call_user_func_array([$logger, $name], $arguments);
}
if (Environment::isGiveDebugEnabled()) {
call_user_func_array([$logger, $name], $arguments);
}
}
/**
* @since 2.20.0
*
* Retrieves the redaction list after applying filters.
*/
public static function getRedactionList(): array
{
static $list = null;
if ($list === null) {
$list = apply_filters('give_log_redaction_list', ['card', 'password', 'secret', 'token']);
}
return $list;
}
}