Passed
Push — hans/Index-all-fluent-options ( 2862f3...50ba63 )
by Simon
13:45 queued 11:38
created

SiteState::withState()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 8
ccs 3
cts 3
cp 1
crap 2
rs 10
1
<?php
2
3
4
namespace Firesphere\SolrSearch\States;
5
6
use Firesphere\SolrSearch\Compat\FluentExtension;
7
use Firesphere\SolrSearch\Helpers\FieldResolver;
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
 * {@see 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
    /**
55
     * Get available states
56
     *
57
     * @return array
58
     */
59 12
    public static function getStates(): array
60
    {
61 12
        return self::$states;
62
    }
63
64
    /**
65
     * Set states
66
     *
67
     * @param array $states
68
     */
69 1
    public static function setStates(array $states): void
70
    {
71 1
        self::$states = $states;
72 1
    }
73
74
    /**
75
     * Add a state
76
     *
77
     * @param $state
78
     */
79 1
    public static function addState($state): void
80
    {
81 1
        self::$states[] = $state;
82 1
    }
83
84
    /**
85
     * Add multiple states
86
     *
87
     * @param array $states
88
     */
89 1
    public static function addStates(array $states): void
90
    {
91 1
        self::$states = array_merge(self::$states, $states);
92 1
    }
93
94
    /**
95
     * Does this class, it's parent (or optionally one of it's children) have the passed extension attached?
96
     *
97
     * @param $class
98
     * @param $extension
99
     * @return bool
100
     * @throws ReflectionException
101
     */
102 1
    public static function hasExtension($class, $extension): bool
103
    {
104
        /** @var DataObject $relatedclass */
105 1
        foreach (FieldResolver::gethierarchy($class) as $relatedclass) {
106 1
            if ($relatedclass::has_extension($extension)) {
107 1
                return true;
108
            }
109
        }
110 1
        return false;
111
    }
112
113
    /**
114
     * Get the current state of every variant
115
     *
116
     * @static
117
     * @return array
118
     * @throws ReflectionException
119
     */
120 13
    public static function currentStates(): array
121
    {
122 13
        $state = [];
123 13
        foreach (self::variants() as $variant => $instance) {
124 12
            $state[$variant] = $instance->currentState();
125
        }
126
127 13
        return $state;
128
    }
129
130
    /**
131
     * Returns an array of variants.
132
     *
133
     * With no arguments, returns all variants
134
     *
135
     * With a classname as the first argument, returns the variants that apply to that class
136
     * (optionally including subclasses)
137
     *
138
     * @static
139
     * @param bool $force
140
     * @return array - An array of (string)$variantClassName => (Object)$variantInstance pairs
141
     * @throws ReflectionException
142
     */
143 15
    public static function variants($force = false): ?array
144
    {
145
        // Build up and cache a list of all search variants (subclasses of SearchVariant)
146 15
        if (!empty(self::$variants) || $force) {
147 13
            $classes = ClassInfo::subclassesFor(static::class);
148
149 13
            foreach ($classes as $variantclass) {
150 13
                self::isApplicable($variantclass);
151
            }
152
        }
153
154 15
        return self::$variants;
155
    }
156
157
    /**
158
     * Is this extension applied and instantiable
159
     *
160
     * @param $variantclass
161
     * @return bool
162
     * @throws ReflectionException
163
     */
164 14
    public static function isApplicable($variantclass): bool
165
    {
166 14
        $ref = new ReflectionClass($variantclass);
167 14
        if ($ref->isInstantiable()) {
168
            /** @var SiteState $variant */
169 14
            $variant = singleton($variantclass);
170 14
            if ($variant->appliesToEnvironment() && $variant->isEnabled()) {
171 14
                self::$variants[$variantclass] = $variant;
172 14
                return true;
173
            }
174
        }
175
176 14
        return false;
177
    }
178
179
    /**
180
     * Activate a site state for indexing
181
     *
182
     * @param $state
183
     * @throws ReflectionException
184
     */
185 1
    public static function withState($state): void
186
    {
187
        /**
188
         * @var string $variant
189
         * @var static $instance
190
         */
191 1
        foreach (self::variants() as $variant => $instance) {
192 1
            $instance->activateState($state);
193
        }
194 1
    }
195
196
    /**
197
     * Does this state apply to the current object/environment settings
198
     *
199
     * @return bool
200
     */
201
    public function appliesToEnvironment(): bool
202
    {
203
        return $this->enabled;
204
    }
205
206
    /**
207
     * Is this state enabled
208
     *
209
     * @return bool
210
     */
211 14
    public function isEnabled(): bool
212
    {
213 14
        return $this->enabled;
214
    }
215
216
    /**
217
     * Set the state to whatever is required. Most commonly true
218
     *
219
     * @param bool $enabled
220
     */
221 1
    public function setEnabled(bool $enabled): void
222
    {
223 1
        $this->enabled = $enabled;
224 1
    }
225
}
226