-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathArrayRedactor.php
More file actions
152 lines (134 loc) · 3.67 KB
/
ArrayRedactor.php
File metadata and controls
152 lines (134 loc) · 3.67 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php
namespace Mtownsend\ArrayRedactor;
use Mtownsend\ArrayRedactor\Exceptions\ArrayRedactorException;
/**
* @author Mark Townsend
*
*/
class ArrayRedactor
{
/**
* The content to redact (either array of json)
*
* @var mixed array|string
*/
public $content;
/**
* A non-associative array of keys that should be redacted in the content
*
* @var array
*/
public $keys;
/**
* What should replace the redacted data
*
* @var mixed
*/
public $ink;
/**
* Instantiate the ArrayRedactor class
*
* @param mixed array|string $content The content to redact (either array of json)
* @param array $keys A non-associative array of keys that should be redacted in the content
* @param mixed $ink What should replace the redacted data
*/
public function __construct($content = [], array $keys = [], $ink = '[REDACTED]')
{
$this->content = $content;
$this->keys = $keys;
$this->ink = $ink;
}
/**
* Provide the content to undergo redaction
*
* @param mixed array|string $content The content to redact (either array of json)
* @return object \Mtownsend\ArrayRedactor\ArrayRedactor
*/
public function content($content = [])
{
$this->content = $content;
return $this;
}
/**
* Set the keys to redact
*
* @param array $keys A non-associative array of keys that should be redacted in the content
* @return object \Mtownsend\ArrayRedactor\ArrayRedactor
*/
public function keys($keys = [])
{
$this->keys = $keys;
return $this;
}
/**
* Set the value to replace redacted key values with
*
* @param mixed $ink What should replace the redacted data
* @return object \Mtownsend\ArrayRedactor\ArrayRedactor
*/
public function ink($ink = '[REDACTED]')
{
$this->ink = $ink;
return $this;
}
/**
* Apply recursive array redaction to the content
*
* @return array
*/
public function redact()
{
if (is_string($this->content) && $this->isValidJson($this->content)) {
$this->content = json_decode($this->content, true);
}
if (!is_array($this->content) || !$this->isAssocArray($this->content)) {
throw new ArrayRedactorException("ArrayRedactor received invalid content `{$this->content}`");
}
// Recursively traverse the array and redact the specified keys
array_walk_recursive($this->content, function (&$value, $key) {
if (in_array($key, $this->keys, true)) {
$value = is_callable($this->ink) ? call_user_func($this->ink, $value, $key) : $this->ink;
}
});
return $this->content;
}
/**
* Return a json string
*
* @return string
*/
public function redactToJson()
{
return json_encode($this->redact());
}
public function __toString()
{
return $this->redactToJson();
}
public function __invoke()
{
return $this->redact();
}
/**
* Determine if the given array is associative or non-associative
*
* @param array $array
* @return boolean
*/
protected function isAssocArray(array $array)
{
$keys = array_keys($array);
return array_keys($keys) !== $keys;
}
/**
* Check if the string received is valid json
*
* @param string $string Assumed json string
* @return boolean
*/
protected function isValidJson($string)
{
json_decode($string);
return (json_last_error() === JSON_ERROR_NONE);
}
}