1
+ <?php
2
+
3
+ namespace App \Models ;
4
+
5
+
6
+ use Illuminate \Database \Eloquent \Model ;
7
+ use Illuminate \Support \Str ;
8
+
9
+ class RedactedModel extends Model
10
+ {
11
+
12
+ /**
13
+ * The fields that will be hidden or redacted
14
+ * @var array $redacted
15
+ */
16
+ protected $ redacted = [];
17
+
18
+ /**
19
+ * If redact is true a string will be returned instead of the value, otherwise it will be hidden
20
+ * @var bool $redact
21
+ */
22
+ protected $ redact = true ;
23
+
24
+ /**
25
+ * The string that will be returned if redact is true
26
+ * @var string
27
+ */
28
+ protected $ redactedString = '[Hidden Data] ' ;
29
+
30
+ /**
31
+ * Allow the user to override all protection
32
+ * @var bool $protectionDisabled
33
+ */
34
+ private $ protectionDisabled = false ;
35
+
36
+ /**
37
+ * If the redacted value is null, should the key be hidden too.
38
+ * @var bool $redactKeys
39
+ */
40
+ private $ redactKeys = true ;
41
+
42
+ /**
43
+ * Disabled protection for all fields
44
+ */
45
+ public function disableProtection ()
46
+ {
47
+ $ this ->protectionDisabled = true ;
48
+ }
49
+
50
+ /**
51
+ * Enables protection for all fields
52
+ */
53
+ public function enableProtection ()
54
+ {
55
+ $ this ->protectionDisabled = false ;
56
+ }
57
+
58
+ /**
59
+ * Allow protection to be enabled or disabled for certain keys
60
+ * @param $key
61
+ * @return bool
62
+ */
63
+ public function shouldRedactField ($ key )
64
+ {
65
+ return true ;
66
+ }
67
+
68
+ /**
69
+ * Determines if a field is one of the fields marked as protected redacted and the user
70
+ * has specified it should be redacted
71
+ * @param $key
72
+ * @return bool
73
+ */
74
+ private function internalShouldRedactField ($ key )
75
+ {
76
+ return !$ this ->protectionDisabled && in_array ($ key , $ this ->redacted ) && $ this ->shouldRedactField ($ key );
77
+ }
78
+
79
+ /**
80
+ * Override of the laravel getAttribute
81
+ * @param string $key
82
+ * @return mixed|string|null
83
+ */
84
+ public function getAttribute ($ key )
85
+ {
86
+ return $ this ->internalShouldRedactField ($ key )
87
+ ? $ this ->getDataForKey ($ key )
88
+ : parent ::getAttribute ($ key );
89
+ }
90
+
91
+ /**
92
+ * Either return the default hidden value or use the user provided one
93
+ * @param $key
94
+ * @return string|null
95
+ */
96
+ private function getDataForKey ($ key )
97
+ {
98
+ $ functionName = 'get ' .Str::studly ($ key ).'RedactedValue ' ;
99
+ return method_exists ($ this , $ functionName ) ? $ this ->{$ functionName }() : $ this ->defaultRedactedValue ($ key );
100
+ }
101
+
102
+ /**
103
+ * By default return the redactedString or null, allows the user to override this
104
+ * @param $key
105
+ * @return string|null
106
+ */
107
+ public function defaultRedactedValue ($ key )
108
+ {
109
+ return $ this ->redact ? $ this ->redactedString : null ;
110
+ }
111
+
112
+ /**
113
+ * Redact data if the model is access as an array
114
+ * @return array|\Illuminate\Support\Collection
115
+ */
116
+ public function toArray ()
117
+ {
118
+ $ data = parent ::toArray ();
119
+ $ redactedData = [];
120
+
121
+ foreach ($ data as $ key => $ value ) {
122
+ if ($ this ->internalShouldRedactField ($ key )) {
123
+ $ value = $ this ->getAttribute ($ key );
124
+
125
+ if ($ this ->redactKeys && is_null ($ value )) {
126
+ continue ;
127
+ }
128
+ }
129
+
130
+ $ redactedData [$ key ] = $ value ;
131
+ }
132
+
133
+ return $ redactedData ;
134
+ }
135
+ }
0 commit comments