Passed
Push — hans/Index-all-fluent-options ( 33af16...2afa88 )
by Simon
07:48
created

SiteState::addStates()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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