Passed
Push — hans/valid-classes ( 1110df...3598c3 )
by Simon
11:18
created

SiteState::variants()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

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