1
+ <?php
2
+
3
+ namespace WpFacade ;
4
+
5
+ use Mockery \MockInterface ;
6
+
7
+ abstract class WpFacade {
8
+ /** @var \BetterWpHooks\Contracts\EventContainerAdapter */
9
+ private static $ container ;
10
+
11
+
12
+ /**
13
+ * The resolved object instances.
14
+ *
15
+ * @var array
16
+ */
17
+ private static $ resolvedInstance ;
18
+
19
+
20
+ /**
21
+ * Get the root object behind the facade.
22
+ *
23
+ * @return mixed
24
+ */
25
+ public static function getFacadeRoot () {
26
+
27
+ return static ::resolveFacadeInstance ( static ::getFacadeAccessor () );
28
+ }
29
+
30
+
31
+ /**
32
+ * Get the registered name of the component.
33
+ *
34
+ * @return string
35
+ *
36
+ * @throws \RuntimeException
37
+ */
38
+ protected static function getFacadeAccessor () {
39
+
40
+ throw new RuntimeException ( 'Facade does not implement getFacadeAccessor method. ' );
41
+ }
42
+
43
+
44
+
45
+ /**
46
+ * Resolve the facade root instance from the container.
47
+ *
48
+ * @param object|string $name
49
+ *
50
+ * @return mixed
51
+ */
52
+ protected static function resolveFacadeInstance ( $ name ) {
53
+
54
+ if ( is_object ( $ name ) ) {
55
+ return $ name ;
56
+ }
57
+
58
+ if ( isset ( static ::$ resolvedInstance [ $ name ] ) ) {
59
+ return static ::$ resolvedInstance [ $ name ];
60
+ }
61
+
62
+ if ( static ::$ container ) {
63
+
64
+ return static ::$ resolvedInstance [ $ name ] = static ::$ container ->make ( $ name );
65
+
66
+ }
67
+
68
+ }
69
+
70
+
71
+ /**
72
+ * Clear a resolved facade instance.
73
+ *
74
+ * @param string $name
75
+ *
76
+ * @return void
77
+ */
78
+ public static function clearResolvedInstance ( $ name ) {
79
+ unset( static ::$ resolvedInstance [ $ name ] );
80
+ }
81
+
82
+ /**
83
+ * Clear all of the resolved instances.
84
+ *
85
+ * @return void
86
+ */
87
+ public static function clearResolvedInstances () {
88
+
89
+ static ::$ resolvedInstance = [];
90
+
91
+ }
92
+
93
+
94
+ /**
95
+ *
96
+ * @return \BetterWpHooks\Contracts\EventContainerAdapter
97
+ */
98
+ public static function getFacadeContainer (): Contracts \EventContainerAdapter {
99
+
100
+ return static ::$ container ;
101
+
102
+ }
103
+
104
+ /**
105
+ * Set the application instance.
106
+ *
107
+ * @param \BetterWpHooks\Contracts\EventContainerAdapter $container
108
+ *
109
+ * @return void
110
+ */
111
+ public static function setFacadeContainer ( $ container ) {
112
+ static ::$ container = $ container ;
113
+ }
114
+
115
+
116
+ /**
117
+ * Handle dynamic, static calls to the object.
118
+ *
119
+ * @param string $method
120
+ * @param array $args
121
+ *
122
+ * @return mixed
123
+ *
124
+ * @throws \RuntimeException
125
+ */
126
+ public static function __callStatic ( string $ method , array $ args ) {
127
+
128
+ $ instance = static ::getFacadeRoot ();
129
+
130
+ if ( ! $ instance ) {
131
+ throw new RuntimeException ( 'A facade root has not been set. ' );
132
+ }
133
+
134
+
135
+ return $ instance ->$ method ( ...$ args );
136
+
137
+ }
138
+
139
+
140
+ /**
141
+ * Convert the facade into a Mockery spy.
142
+ *
143
+ * @return \Mockery\MockInterface
144
+ */
145
+ public static function spy () {
146
+
147
+ if ( ! static ::isMock () ) {
148
+
149
+ $ class = static ::getMockableClass ();
150
+
151
+ return tap ( $ class ? Mockery::spy ( $ class ) : Mockery::spy (), function ( $ spy ) {
152
+ static ::swap ( $ spy );
153
+ } );
154
+ }
155
+ }
156
+
157
+
158
+ /**
159
+ * Initiate a partial mock on the facade.
160
+ *
161
+ * @return \Mockery\MockInterface
162
+ */
163
+ public static function partialMock () {
164
+ $ name = static ::getFacadeAccessor ();
165
+
166
+ $ mock = static ::isMock ()
167
+ ? static ::$ resolvedInstance [ $ name ]
168
+ : static ::createFreshMockInstance ();
169
+
170
+ return $ mock ->makePartial ();
171
+ }
172
+
173
+ /**
174
+ * Initiate a mock expectation on the facade.
175
+ *
176
+ * @return \Mockery\Expectation
177
+ */
178
+ public static function shouldReceive () {
179
+
180
+ $ name = static ::getFacadeAccessor ();
181
+
182
+ $ mock = static ::isMock ()
183
+ ? static ::$ resolvedInstance [ $ name ]
184
+ : static ::createFreshMockInstance ();
185
+
186
+ return $ mock ->shouldReceive ( ...func_get_args () );
187
+ }
188
+
189
+ /**
190
+ * Create a fresh mock instance for the given class.
191
+ *
192
+ * @return \Mockery\MockInterface
193
+ */
194
+ protected static function createFreshMockInstance () {
195
+ return tap ( static ::createMock (), function ( $ mock ) {
196
+ static ::swap ( $ mock );
197
+
198
+ $ mock ->shouldAllowMockingProtectedMethods ();
199
+ } );
200
+ }
201
+
202
+ /**
203
+ * Create a fresh mock instance for the given class.
204
+ *
205
+ * @return \Mockery\MockInterface
206
+ */
207
+ protected static function createMock () {
208
+ $ class = static ::getMockableClass ();
209
+
210
+ return $ class ? Mockery::mock ( $ class ) : Mockery::mock ();
211
+ }
212
+
213
+ /**
214
+ * Determines whether a mock is set as the instance of the facade.
215
+ *
216
+ * @return bool
217
+ */
218
+ protected static function isMock () {
219
+ $ name = static ::getFacadeAccessor ();
220
+
221
+ return isset ( static ::$ resolvedInstance [ $ name ] ) &&
222
+ static ::$ resolvedInstance [ $ name ] instanceof MockInterface;
223
+ }
224
+
225
+ /**
226
+ * Get the mockable class for the bound instance.
227
+ *
228
+ * @return string|null
229
+ */
230
+ protected static function getMockableClass () {
231
+ if ( $ root = static ::getFacadeRoot () ) {
232
+ return get_class ( $ root );
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Hotswap the underlying instance behind the facade.
238
+ *
239
+ * @param mixed $instance
240
+ *
241
+ * @return void
242
+ */
243
+ public static function swap ( $ instance ) {
244
+
245
+ static ::$ resolvedInstance [ static ::getFacadeAccessor () ] = $ instance ;
246
+
247
+ if ( isset ( static ::$ container ) ) {
248
+ static ::$ container ->swapInstance ( static ::getFacadeAccessor (), $ instance );
249
+ }
250
+
251
+ }
252
+ }
0 commit comments