1: | <?php declare(strict_types=1); |
2: | |
3: | namespace Salient\Core\Concern; |
4: | |
5: | use Salient\Contract\Core\FacadeAwareInterface; |
6: | use Salient\Contract\Core\FacadeInterface; |
7: | use Salient\Utility\Get; |
8: | use LogicException; |
9: | |
10: | /** |
11: | * Implements FacadeAwareInterface by maintaining a list of facades the instance |
12: | * is being used by |
13: | * |
14: | * @see FacadeAwareInterface |
15: | * |
16: | * @api |
17: | * |
18: | * @template TFacade of FacadeInterface |
19: | */ |
20: | trait UnloadsFacades |
21: | { |
22: | /** |
23: | * Normalised FQCN => given FQCN |
24: | * |
25: | * @var array<class-string<TFacade>,class-string<TFacade>> |
26: | */ |
27: | private $Facades = []; |
28: | |
29: | /** |
30: | * @param class-string<TFacade> $facade |
31: | * @return static |
32: | */ |
33: | final public function withFacade(string $facade) |
34: | { |
35: | $this->Facades[Get::fqcn($facade)] = $facade; |
36: | return $this; |
37: | } |
38: | |
39: | /** |
40: | * @param class-string<TFacade> $facade |
41: | * @return static |
42: | */ |
43: | final public function withoutFacade(string $facade, bool $unloading) |
44: | { |
45: | if ($unloading) { |
46: | unset($this->Facades[Get::fqcn($facade)]); |
47: | } |
48: | return $this; |
49: | } |
50: | |
51: | /** |
52: | * Unload any facades where the object is the underlying instance |
53: | */ |
54: | final protected function unloadFacades(): void |
55: | { |
56: | if (!$this->Facades) { |
57: | return; |
58: | } |
59: | |
60: | foreach ($this->Facades as $fqcn => $facade) { |
61: | if (!$facade::isLoaded() || $facade::getInstance() !== $this) { |
62: | // @codeCoverageIgnoreStart |
63: | unset($this->Facades[$fqcn]); |
64: | continue; |
65: | // @codeCoverageIgnoreEnd |
66: | } |
67: | |
68: | $facade::unload(); |
69: | } |
70: | |
71: | if (!$this->Facades) { |
72: | return; |
73: | } |
74: | |
75: | // @codeCoverageIgnoreStart |
76: | throw new LogicException(sprintf( |
77: | 'Underlying %s not unloaded: %s', |
78: | static::class, |
79: | implode(' ', $this->Facades), |
80: | )); |
81: | // @codeCoverageIgnoreEnd |
82: | } |
83: | } |
84: |