-
-
Notifications
You must be signed in to change notification settings - Fork 574
Expand file tree
/
Copy pathWarning.php
More file actions
127 lines (114 loc) · 3.98 KB
/
Warning.php
File metadata and controls
127 lines (114 loc) · 3.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php declare(strict_types=1);
namespace GraphQL\Error;
/**
* Encapsulates warnings produced by the library.
*
* Warnings can be suppressed (individually or all) if required.
* Also, it is possible to override warning handler (which is **trigger_error()** by default).
*
* @phpstan-type WarningHandler callable(string $errorMessage, int $warningId, ?int $messageLevel): void
*/
final class Warning
{
public const NONE = 0;
public const WARNING_ASSIGN = 2;
public const WARNING_CONFIG = 4;
public const WARNING_FULL_SCHEMA_SCAN = 8;
public const WARNING_CONFIG_DEPRECATION = 16;
public const WARNING_NOT_A_TYPE = 32;
public const ALL = 63;
private static int $enableWarnings = self::ALL;
/** @var array<int, true> */
private static array $warned = [];
/**
* @var callable|null
*
* @phpstan-var WarningHandler|null
*/
private static $warningHandler;
/**
* Sets warning handler which can intercept all system warnings.
* When not set, trigger_error() is used to notify about warnings.
*
* @phpstan-param WarningHandler|null $warningHandler
*
* @api
*/
public static function setWarningHandler(?callable $warningHandler): void
{
self::$warningHandler = $warningHandler;
}
/**
* Suppress warning by id (has no effect when custom warning handler is set).
*
* @param bool|int $suppress
*
* @example Warning::suppress(Warning::WARNING_NOT_A_TYPE) suppress a specific warning
* @example Warning::suppress(true) suppresses all warnings
* @example Warning::suppress(false) enables all warnings
*
* @api
*/
public static function suppress($suppress = true): void
{
if ($suppress === true) {
self::$enableWarnings = self::NONE;
} elseif ($suppress === false) {
self::$enableWarnings = self::ALL;
// @phpstan-ignore-next-line necessary until we can use proper unions
} elseif (\is_int($suppress)) {
self::$enableWarnings &= ~$suppress;
} else {
$type = \gettype($suppress);
throw new \InvalidArgumentException("Expected type bool|int, got {$type}.");
}
}
/**
* Re-enable previously suppressed warning by id (has no effect when custom warning handler is set).
*
* @param bool|int $enable
*
* @example Warning::suppress(Warning::WARNING_NOT_A_TYPE) re-enables a specific warning
* @example Warning::suppress(true) re-enables all warnings
* @example Warning::suppress(false) suppresses all warnings
*
* @api
*/
public static function enable($enable = true): void
{
if ($enable === true) {
self::$enableWarnings = self::ALL;
} elseif ($enable === false) {
self::$enableWarnings = self::NONE;
// @phpstan-ignore-next-line necessary until we can use proper unions
} elseif (\is_int($enable)) {
self::$enableWarnings |= $enable;
} else {
$type = \gettype($enable);
throw new \InvalidArgumentException("Expected type bool|int, got {$type}.");
}
}
public static function warnOnce(string $errorMessage, int $warningId, int $messageLevel = \E_USER_WARNING): void
{
if (isset(self::$warned[$warningId])) {
return;
}
self::warn($errorMessage, $warningId, $messageLevel);
}
public static function warn(string $errorMessage, int $warningId, int $messageLevel = \E_USER_WARNING): void
{
if (! self::shouldWarn($warningId)) {
return;
}
self::$warned[$warningId] = true;
if (isset(self::$warningHandler)) {
(self::$warningHandler)($errorMessage, $warningId, $messageLevel);
} else {
\trigger_error($errorMessage, $messageLevel);
}
}
private static function shouldWarn(int $warningId): bool
{
return (self::$enableWarnings & $warningId) > 0;
}
}