Passed
Push — hans/core-extraction ( a44af8...403a8e )
by Simon
36:58 queued 04:22
created

SiteState   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 202
Duplicated Lines 0 %

Test Coverage

Coverage 95.83%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 40
c 1
b 0
f 0
dl 0
loc 202
ccs 46
cts 48
cp 0.9583
rs 10
wmc 24

12 Methods

Rating   Name   Duplication   Size   Complexity  
A currentStates() 0 8 2
A variants() 0 12 4
A addStates() 0 3 1
A setEnabled() 0 3 1
A addState() 0 3 1
A appliesToEnvironment() 0 3 1
A hasExtension() 0 10 3
A withState() 0 11 4
A isEnabled() 0 3 1
A getStates() 0 3 1
A setStates() 0 3 1
A isApplicable() 0 14 4
1
<?php
2
3
4
namespace Firesphere\SolrSearch\States;
5
6
use Firesphere\SolrSearch\Helpers\FieldResolver;
7
use Firesphere\SolrSearch\Interfaces\SiteStateInterface;
8
use ReflectionClass;
9
use ReflectionException;
10
use SilverStripe\Core\ClassInfo;
11
use SilverStripe\Core\Config\Configurable;
12
use SilverStripe\Core\Injector\Injectable;
13
use SilverStripe\ORM\DataObject;
14
15
/**
16
 * Class SiteState
17
 *
18
 * Determine and apply the state of the site currently. This is used at index-time to figure out what state to index.
19
 * An example of this is the FluentSearchVariant extension from Fluent.
20
 *
21
 * Fluent uses the old SearchVariant method, which is actually not that bad a concept. These "Variants", now called
22
 * "States" set the state of the site to a required setting for each available state.
23
 *
24
 * States SHOULD add their own states through an extension, otherwise it won't be called.
25
 * {@link FluentExtension::onBeforeInit()}
26
 *
27
 * States, options, etc. are simplified for a more streamlined approach
28
 *
29
 * @package Firesphere\SolrSearch\States
30
 */
31
abstract class SiteState
32
{
33
    use Configurable;
34
    use Injectable;
35
    /**
36
     * States that can be applied
37
     *
38
     * @var array
39
     */
40
    public static $states = [
41
        'default',
42
    ];
43
    /**
44
     * Variants of SiteState that can be activated
45
     *
46
     * @var array
47
     */
48
    public static $variants = [];
49
    /**
50
     * @var bool Is this State enabled
51
     */
52
    public $enabled = true;
53
    /**
54
     * @var string Current state
55
     */
56
    protected $state;
57
58
    /**
59
     * Get available states
60
     *
61
     * @static
62
     * @return array
63
     */
64 14
    public static function getStates(): array
65
    {
66 14
        return self::$states;
67
    }
68
69
    /**
70
     * Set states
71
     *
72
     * @static
73
     * @param array $states
74
     */
75 1
    public static function setStates(array $states): void
76
    {
77 1
        self::$states = $states;
78 1
    }
79
80
    /**
81
     * Add a state
82
     *
83
     * @static
84
     * @param $state
85
     */
86 1
    public static function addState($state): void
87
    {
88 1
        self::$states[] = $state;
89 1
    }
90
91
    /**
92
     * Add multiple states
93
     *
94
     * @static
95
     * @param array $states
96
     */
97 1
    public static function addStates(array $states): void
98
    {
99 1
        self::$states = array_merge(self::$states, $states);
100 1
    }
101
102
    /**
103
     * Does this class, it's parent (or optionally one of it's children) have the passed extension attached?
104
     *
105
     * @static
106
     * @param $class
107
     * @param $extension
108
     * @return bool
109
     * @throws ReflectionException
110
     */
111 1
    public static function hasExtension($class, $extension): bool
112
    {
113
        /** @var DataObject $relatedclass */
114 1
        foreach (FieldResolver::gethierarchy($class) as $relatedclass) {
115 1
            if ($relatedclass::has_extension($extension)) {
116 1
                return true;
117
            }
118
        }
119
120 1
        return false;
121
    }
122
123
    /**
124
     * Get the current state of every variant
125
     *
126
     * @static
127
     * @return array
128
     * @throws ReflectionException
129
     */
130 15
    public static function currentStates(): array
131
    {
132 15
        $state = [];
133 15
        foreach (self::variants() as $variant => $instance) {
134 14
            $state[$variant] = $instance->currentState();
135
        }
136
137 15
        return $state;
138
    }
139
140
    /**
141
     * Returns an array of variants.
142
     *
143
     * @static
144
     * @param bool $force Force updating the variants
145
     * @return array - An array of (string)$variantClassName => (Object)$variantInstance pairs
146
     * @throws ReflectionException
147
     */
148 17
    public static function variants($force = false): array
149
    {
150
        // Build up and cache a list of all search variants (subclasses of SearchVariant)
151 17
        if (!empty(self::$variants) || $force) {
152 15
            $classes = ClassInfo::subclassesFor(static::class);
153
154 15
            foreach ($classes as $variantclass) {
155 15
                self::isApplicable($variantclass);
156
            }
157
        }
158
159 17
        return self::$variants;
160
    }
161
162
    /**
163
     * Is this extension applied and instantiable
164
     *
165
     * @static
166
     * @param $variantclass
167
     * @return bool
168
     * @throws ReflectionException
169
     */
170 16
    public static function isApplicable($variantclass): bool
171
    {
172 16
        $ref = new ReflectionClass($variantclass);
173 16
        if ($ref->isInstantiable()) {
174
            /** @var SiteState $variant */
175 16
            $variant = singleton($variantclass);
176 16
            if ($variant->appliesToEnvironment() && $variant->isEnabled()) {
177 16
                self::$variants[$variantclass] = $variant;
178
179 16
                return true;
180
            }
181
        }
182
183 16
        return false;
184
    }
185
186
    /**
187
     * Does this state apply to the current object/environment settings
188
     *
189
     * @return bool
190
     */
191
    public function appliesToEnvironment(): bool
192
    {
193
        return $this->enabled;
194
    }
195
196
    /**
197
     * Is this state enabled
198
     *
199
     * @return bool
200
     */
201 16
    public function isEnabled(): bool
202
    {
203 16
        return $this->enabled;
204
    }
205
206
    /**
207
     * Set the state to whatever is required. Most commonly true
208
     *
209
     * @param bool $enabled
210
     */
211 1
    public function setEnabled(bool $enabled): void
212
    {
213 1
        $this->enabled = $enabled;
214 1
    }
215
216
    /**
217
     * Activate a site state for indexing
218
     *
219
     * @param $state
220
     * @throws ReflectionException
221
     */
222 1
    public static function withState($state): void
223
    {
224
        /**
225
         * @var string $variant
226
         * @var SiteStateInterface $instance
227
         */
228 1
        foreach (self::variants() as $variant => $instance) {
229 1
            if ($state === 'default') {
230 1
                $instance->setDefaultState();
231 1
            } elseif ($instance->stateIsApplicable($state)) {
232 1
                $instance->activateState($state);
233
            }
234
        }
235 1
    }
236
}
237