Current File : /www/capitalgmcbuickregina_830/public/wp-content/plugins/ninja-forms-uploads/lib/Monolog/Logger.php
<?php declare(strict_types=1);
/*
* This file is part of the Monolog package.
*
* (c) Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace NF_FU_LIB\Monolog;
use DateTimeZone;
use NF_FU_LIB\Monolog\Handler\HandlerInterface;
use NF_FU_LIB\Psr\Log\LoggerInterface;
use NF_FU_LIB\Psr\Log\InvalidArgumentException;
use NF_FU_LIB\Psr\Log\LogLevel;
use Throwable;
use Stringable;
/**
* Monolog log channel
*
* It contains a stack of Handlers and a stack of Processors,
* and uses them to store records that are added to it.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*
* @phpstan-type Level Logger::DEBUG|Logger::INFO|Logger::NOTICE|Logger::WARNING|Logger::ERROR|Logger::CRITICAL|Logger::ALERT|Logger::EMERGENCY
* @phpstan-type LevelName 'DEBUG'|'INFO'|'NOTICE'|'WARNING'|'ERROR'|'CRITICAL'|'ALERT'|'EMERGENCY'
* @phpstan-type Record array{message: string, context: mixed[], level: Level, level_name: LevelName, channel: string, datetime: \DateTimeImmutable, extra: mixed[]}
*/
class Logger implements LoggerInterface, ResettableInterface
{
/**
* Detailed debug information
*/
public const DEBUG = 100;
/**
* Interesting events
*
* Examples: User logs in, SQL logs.
*/
public const INFO = 200;
/**
* Uncommon events
*/
public const NOTICE = 250;
/**
* Exceptional occurrences that are not errors
*
* Examples: Use of deprecated APIs, poor use of an API,
* undesirable things that are not necessarily wrong.
*/
public const WARNING = 300;
/**
* Runtime errors
*/
public const ERROR = 400;
/**
* Critical conditions
*
* Example: Application component unavailable, unexpected exception.
*/
public const CRITICAL = 500;
/**
* Action must be taken immediately
*
* Example: Entire website down, database unavailable, etc.
* This should trigger the SMS alerts and wake you up.
*/
public const ALERT = 550;
/**
* Urgent alert.
*/
public const EMERGENCY = 600;
/**
* Monolog API version
*
* This is only bumped when API breaks are done and should
* follow the major version of the library
*
* @var int
*/
public const API = 2;
/**
* This is a static variable and not a constant to serve as an extension point for custom levels
*
* @var array<int, string> $levels Logging levels with the levels as key
*
* @phpstan-var array<Level, LevelName> $levels Logging levels with the levels as key
*/
protected static $levels = [
self::DEBUG => 'DEBUG',
self::INFO => 'INFO',
self::NOTICE => 'NOTICE',
self::WARNING => 'WARNING',
self::ERROR => 'ERROR',
self::CRITICAL => 'CRITICAL',
self::ALERT => 'ALERT',
self::EMERGENCY => 'EMERGENCY',
];
/**
* Mapping between levels numbers defined in RFC 5424 and Monolog ones
*
* @phpstan-var array<int, Level> $rfc_5424_levels
*/
private const RFC_5424_LEVELS = [
7 => self::DEBUG,
6 => self::INFO,
5 => self::NOTICE,
4 => self::WARNING,
3 => self::ERROR,
2 => self::CRITICAL,
1 => self::ALERT,
0 => self::EMERGENCY,
];
/**
* @var string
*/
protected $name;
/**
* The handler stack
*
* @var HandlerInterface[]
*/
protected $handlers;
/**
* Processors that will process all log records
*
* To process records of a single handler instead, add the processor on that specific handler
*
* @var callable[]
*/
protected $processors;
/**
* @var bool
*/
protected $microsecondTimestamps = true;
/**
* @var DateTimeZone
*/
protected $timezone;
/**
* @var callable|null
*/
protected $exceptionHandler;
/**
* @var int Keeps track of depth to prevent infinite logging loops
*/
private $logDepth = 0;
/**
* @var \WeakMap<\Fiber, int>|null Keeps track of depth inside fibers to prevent infinite logging loops
*/
private $fiberLogDepth;
/**
* @var bool Whether to detect infinite logging loops
*
* This can be disabled via {@see useLoggingLoopDetection} if you have async handlers that do not play well with this
*/
private $detectCycles = true;
/**
* @psalm-param array<callable(array): array> $processors
*
* @param string $name The logging channel, a simple descriptive name that is attached to all log records
* @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc.
* @param callable[] $processors Optional array of processors
* @param DateTimeZone|null $timezone Optional timezone, if not provided date_default_timezone_get() will be used
*/
public function __construct(string $name, array $handlers = [], array $processors = [], ?DateTimeZone $timezone = null)
{
$this->name = $name;
$this->setHandlers($handlers);
$this->processors = $processors;
$this->timezone = $timezone ?: new DateTimeZone(date_default_timezone_get() ?: 'UTC');
if (\PHP_VERSION_ID >= 80100) {
// Local variable for phpstan, see https://github.com/phpstan/phpstan/issues/6732#issuecomment-1111118412
/** @var \WeakMap<\Fiber, int> $fiberLogDepth */
$fiberLogDepth = new \WeakMap();
$this->fiberLogDepth = $fiberLogDepth;
}
}
public function getName(): string
{
return $this->name;
}
/**
* Return a new cloned instance with the name changed
*/
public function withName(string $name): self
{
$new = clone $this;
$new->name = $name;
return $new;
}
/**
* Pushes a handler on to the stack.
*/
public function pushHandler(HandlerInterface $handler): self
{
array_unshift($this->handlers, $handler);
return $this;
}
/**
* Pops a handler from the stack
*
* @throws \LogicException If empty handler stack
*/
public function popHandler(): HandlerInterface
{
if (!$this->handlers) {
throw new \LogicException('You tried to pop from an empty handler stack.');
}
return array_shift($this->handlers);
}
/**
* Set handlers, replacing all existing ones.
*
* If a map is passed, keys will be ignored.
*
* @param HandlerInterface[] $handlers
*/
public function setHandlers(array $handlers): self
{
$this->handlers = [];
foreach (array_reverse($handlers) as $handler) {
$this->pushHandler($handler);
}
return $this;
}
/**
* @return HandlerInterface[]
*/
public function getHandlers(): array
{
return $this->handlers;
}
/**
* Adds a processor on to the stack.
*/
public function pushProcessor(callable $callback): self
{
array_unshift($this->processors, $callback);
return $this;
}
/**
* Removes the processor on top of the stack and returns it.
*
* @throws \LogicException If empty processor stack
* @return callable
*/
public function popProcessor(): callable
{
if (!$this->processors) {
throw new \LogicException('You tried to pop from an empty processor stack.');
}
return array_shift($this->processors);
}
/**
* @return callable[]
*/
public function getProcessors(): array
{
return $this->processors;
}
/**
* Control the use of microsecond resolution timestamps in the 'datetime'
* member of new records.
*
* As of PHP7.1 microseconds are always included by the engine, so
* there is no performance penalty and Monolog 2 enabled microseconds
* by default. This function lets you disable them though in case you want
* to suppress microseconds from the output.
*
* @param bool $micro True to use microtime() to create timestamps
*/
public function useMicrosecondTimestamps(bool $micro): self
{
$this->microsecondTimestamps = $micro;
return $this;
}
public function useLoggingLoopDetection(bool $detectCycles): self
{
$this->detectCycles = $detectCycles;
return $this;
}
/**
* Adds a log record.
*
* @param int $level The logging level (a Monolog or RFC 5424 level)
* @param string $message The log message
* @param mixed[] $context The log context
* @param DateTimeImmutable $datetime Optional log date to log into the past or future
* @return bool Whether the record has been processed
*
* @phpstan-param Level $level
*/
public function addRecord(int $level, string $message, array $context = [], ?DateTimeImmutable $datetime = null): bool
{
if (isset(self::RFC_5424_LEVELS[$level])) {
$level = self::RFC_5424_LEVELS[$level];
}
if ($this->detectCycles) {
if (\PHP_VERSION_ID >= 80100 && $fiber = \Fiber::getCurrent()) {
$this->fiberLogDepth[$fiber] = $this->fiberLogDepth[$fiber] ?? 0;
$logDepth = ++$this->fiberLogDepth[$fiber];
} else {
$logDepth = ++$this->logDepth;
}
} else {
$logDepth = 0;
}
if ($logDepth === 3) {
$this->warning('A possible infinite logging loop was detected and aborted. It appears some of your handler code is triggering logging, see the previous log record for a hint as to what may be the cause.');
return false;
} elseif ($logDepth >= 5) { // log depth 4 is let through, so we can log the warning above
return false;
}
try {
$record = null;
foreach ($this->handlers as $handler) {
if (null === $record) {
// skip creating the record as long as no handler is going to handle it
if (!$handler->isHandling(['level' => $level])) {
continue;
}
$levelName = static::getLevelName($level);
$record = [
'message' => $message,
'context' => $context,
'level' => $level,
'level_name' => $levelName,
'channel' => $this->name,
'datetime' => $datetime ?? new DateTimeImmutable($this->microsecondTimestamps, $this->timezone),
'extra' => [],
];
try {
foreach ($this->processors as $processor) {
$record = $processor($record);
}
} catch (Throwable $e) {
$this->handleException($e, $record);
return true;
}
}
// once the record exists, send it to all handlers as long as the bubbling chain is not interrupted
try {
if (true === $handler->handle($record)) {
break;
}
} catch (Throwable $e) {
$this->handleException($e, $record);
return true;
}
}
} finally {
if ($this->detectCycles) {
if (isset($fiber)) {
$this->fiberLogDepth[$fiber]--;
} else {
$this->logDepth--;
}
}
}
return null !== $record;
}
/**
* Ends a log cycle and frees all resources used by handlers.
*
* Closing a Handler means flushing all buffers and freeing any open resources/handles.
* Handlers that have been closed should be able to accept log records again and re-open
* themselves on demand, but this may not always be possible depending on implementation.
*
* This is useful at the end of a request and will be called automatically on every handler
* when they get destructed.
*/
public function close(): void
{
foreach ($this->handlers as $handler) {
$handler->close();
}
}
/**
* Ends a log cycle and resets all handlers and processors to their initial state.
*
* Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal
* state, and getting it back to a state in which it can receive log records again.
*
* This is useful in case you want to avoid logs leaking between two requests or jobs when you
* have a long running process like a worker or an application server serving multiple requests
* in one process.
*/
public function reset(): void
{
foreach ($this->handlers as $handler) {
if ($handler instanceof ResettableInterface) {
$handler->reset();
}
}
foreach ($this->processors as $processor) {
if ($processor instanceof ResettableInterface) {
$processor->reset();
}
}
}
/**
* Gets all supported logging levels.
*
* @return array<string, int> Assoc array with human-readable level names => level codes.
* @phpstan-return array<LevelName, Level>
*/
public static function getLevels(): array
{
return array_flip(static::$levels);
}
/**
* Gets the name of the logging level.
*
* @throws \Psr\Log\InvalidArgumentException If level is not defined
*
* @phpstan-param Level $level
* @phpstan-return LevelName
*/
public static function getLevelName(int $level): string
{
if (!isset(static::$levels[$level])) {
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
}
return static::$levels[$level];
}
/**
* Converts PSR-3 levels to Monolog ones if necessary
*
* @param string|int $level Level number (monolog) or name (PSR-3)
* @throws \Psr\Log\InvalidArgumentException If level is not defined
*
* @phpstan-param Level|LevelName|LogLevel::* $level
* @phpstan-return Level
*/
public static function toMonologLevel($level): int
{
if (is_string($level)) {
if (is_numeric($level)) {
/** @phpstan-ignore-next-line */
return intval($level);
}
// Contains chars of all log levels and avoids using strtoupper() which may have
// strange results depending on locale (for example, "i" will become "İ" in Turkish locale)
$upper = strtr($level, 'abcdefgilmnortuwy', 'ABCDEFGILMNORTUWY');
if (defined(__CLASS__.'::'.$upper)) {
return constant(__CLASS__ . '::' . $upper);
}
throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
}
if (!is_int($level)) {
throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', array_keys(static::$levels) + static::$levels));
}
return $level;
}
/**
* Checks whether the Logger has a handler that listens on the given level
*
* @phpstan-param Level $level
*/
public function isHandling(int $level): bool
{
$record = [
'level' => $level,
];
foreach ($this->handlers as $handler) {
if ($handler->isHandling($record)) {
return true;
}
}
return false;
}
/**
* Set a custom exception handler that will be called if adding a new record fails
*
* The callable will receive an exception object and the record that failed to be logged
*/
public function setExceptionHandler(?callable $callback): self
{
$this->exceptionHandler = $callback;
return $this;
}
public function getExceptionHandler(): ?callable
{
return $this->exceptionHandler;
}
/**
* Adds a log record at an arbitrary level.
*
* This method allows for compatibility with common interfaces.
*
* @param mixed $level The log level (a Monolog, PSR-3 or RFC 5424 level)
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*
* @phpstan-param Level|LevelName|LogLevel::* $level
*/
public function log($level, $message, array $context = []): void
{
if (!is_int($level) && !is_string($level)) {
throw new \InvalidArgumentException('$level is expected to be a string or int');
}
if (isset(self::RFC_5424_LEVELS[$level])) {
$level = self::RFC_5424_LEVELS[$level];
}
$level = static::toMonologLevel($level);
$this->addRecord($level, (string) $message, $context);
}
/**
* Adds a log record at the DEBUG level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function debug($message, array $context = []): void
{
$this->addRecord(static::DEBUG, (string) $message, $context);
}
/**
* Adds a log record at the INFO level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function info($message, array $context = []): void
{
$this->addRecord(static::INFO, (string) $message, $context);
}
/**
* Adds a log record at the NOTICE level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function notice($message, array $context = []): void
{
$this->addRecord(static::NOTICE, (string) $message, $context);
}
/**
* Adds a log record at the WARNING level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function warning($message, array $context = []): void
{
$this->addRecord(static::WARNING, (string) $message, $context);
}
/**
* Adds a log record at the ERROR level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function error($message, array $context = []): void
{
$this->addRecord(static::ERROR, (string) $message, $context);
}
/**
* Adds a log record at the CRITICAL level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function critical($message, array $context = []): void
{
$this->addRecord(static::CRITICAL, (string) $message, $context);
}
/**
* Adds a log record at the ALERT level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function alert($message, array $context = []): void
{
$this->addRecord(static::ALERT, (string) $message, $context);
}
/**
* Adds a log record at the EMERGENCY level.
*
* This method allows for compatibility with common interfaces.
*
* @param string|Stringable $message The log message
* @param mixed[] $context The log context
*/
public function emergency($message, array $context = []): void
{
$this->addRecord(static::EMERGENCY, (string) $message, $context);
}
/**
* Sets the timezone to be used for the timestamp of log records.
*/
public function setTimezone(DateTimeZone $tz): self
{
$this->timezone = $tz;
return $this;
}
/**
* Returns the timezone to be used for the timestamp of log records.
*/
public function getTimezone(): DateTimeZone
{
return $this->timezone;
}
/**
* Delegates exception management to the custom exception handler,
* or throws the exception if no custom handler is set.
*
* @param array $record
* @phpstan-param Record $record
*/
protected function handleException(Throwable $e, array $record): void
{
if (!$this->exceptionHandler) {
throw $e;
}
($this->exceptionHandler)($e, $record);
}
/**
* @return array<string, mixed>
*/
public function __serialize(): array
{
return [
'name' => $this->name,
'handlers' => $this->handlers,
'processors' => $this->processors,
'microsecondTimestamps' => $this->microsecondTimestamps,
'timezone' => $this->timezone,
'exceptionHandler' => $this->exceptionHandler,
'logDepth' => $this->logDepth,
'detectCycles' => $this->detectCycles,
];
}
/**
* @param array<string, mixed> $data
*/
public function __unserialize(array $data): void
{
foreach (['name', 'handlers', 'processors', 'microsecondTimestamps', 'timezone', 'exceptionHandler', 'logDepth', 'detectCycles'] as $property) {
if (isset($data[$property])) {
$this->$property = $data[$property];
}
}
if (\PHP_VERSION_ID >= 80100) {
// Local variable for phpstan, see https://github.com/phpstan/phpstan/issues/6732#issuecomment-1111118412
/** @var \WeakMap<\Fiber, int> $fiberLogDepth */
$fiberLogDepth = new \WeakMap();
$this->fiberLogDepth = $fiberLogDepth;
}
}
}
Thank you for choosing Capital GMC Buick | Regina, your premier certified Buick and GMC dealership proudly serving drivers in Regina and the surrounding communities. Whether you’re searching for a brand-new Buick or GMC vehicle or a meticulously inspected pre-owned model, we have a diverse selection to match your needs and lifestyle.
Beyond our impressive inventory, we offer a seamless and stress-free financing experience through our well-connected finance centre, where our team of experts is dedicated to securing the best loan or lease options for you, quickly, transparently, and hassle-free.
But our commitment to you doesn’t stop at the sale. Our state-of-the-art service centre is staffed with skilled Buick and GMC technicians who use the latest equipment and genuine OEM parts to keep your vehicle running at its best. From routine maintenance to complex repairs, we’ve got you covered.
Experience top-tier customer service, quality vehicles, and expert care, all in one place. Visit Capital GMC Buick | Regina today or call us at 306-205-8072 with any questions. We’re here to help!
Have a question or need assistance? Fill out the form and we will reach out to you as soon as possible.
Schedule a Visit
Let us know when you are coming and how we can assist you. We can ensure someone will be on hand to help you out at the desired date and time.
Find a Career
Have a look at our list of available positions and apply online today to join our team!
Opportunities to Grow
The auto industry is constantly changing and we want to continue to grow. We offer growth, leadership & mentorship programs to allow our staff to grow with us.
Competitive Salary
We have a significant earning potential with incentive-based pay in most roles. We also offer an employee referral bonus with paid bonuses.
Health & Dental
We offer a comprehensive benefits package including extended health, dental, and vision care. We also include paramedical, life insurance, paid sick leave, short & long-term disability coverages.
Vacation
We value our employees and want everyone to take their vacation time. We offer a minimum of 2 weeks vacation each year.
Training & Development
We have many opportunities for paid education and training in-house as well as training from the Manufacturer.
$10,000 Cash Giveaway – Terms & Conditions
All October long, stop by Capital GMC Buick Cadillac, to enter for your chance to win $10,000 cash. No purchase is required, but entries must be made in-store.
The contest is open to residents of Saskatchewan who are 18+. Dealership employees and their households are not eligible. Entries will be accepted from October 1 to October 31, 2025. A random draw will take place on November 1, 2025.
The prize is one $10,000 award, paid by cheque, and must be accepted as awarded. Winner will be contacted by phone or email and must respond within 7 days or another entry may be drawn. Odds of winning depend on the number of entries received.By entering, you agree that Capital Automotive Group may use your name and photo for winner announcements. The contest is governed by the laws of Saskatchewan.