GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

SlotMachine   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 279
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 3
dl 0
loc 279
c 0
b 0
f 0
rs 9.6

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
B initialize() 0 30 7
A translateUndefinedCardResolution() 0 8 2
A interpolate() 0 21 4
B get() 0 38 6
A resolveIndex() 0 19 4
A setRequest() 0 4 1
A getRequest() 0 4 1
A getConfig() 0 4 1
A count() 0 12 3
A all() 0 11 2
A toJson() 0 4 1
A __toString() 0 4 1
1
<?php
2
3
/*
4
 * This file is part of the SlotMachine library.
5
 *
6
 * (c) Adam Elsodaney <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace SlotMachine;
13
14
use Symfony\Component\HttpFoundation\Request;
15
16
/**
17
 * SlotMachine is a content container for dynamic pages written for PHP 5.3 and
18
 * above. Each component on a page that can change its value is called a slot,
19
 * and works is much the same way a slot machine does, except that the slot's
20
 * cards are not randomly displayed, (but it can be if you wanted it to).
21
 *
22
 * Please visit the official git repository for any issues you may have.
23
 *
24
 * @link https://github.com/archfizz/slotmachine
25
 *
26
 * @author Adam Elsodaney <[email protected]>
27
 */
28
class SlotMachine extends \Pimple implements \Countable
29
{
30
    const VERSION = '2.0.0';
31
    const MAJOR_VERSION = 2;
32
    const MINOR_VERSION = 0;
33
    const PATCH_VERSION = 0;
34
35
    /**
36
     * @var array
37
     */
38
    protected $config;
39
40
    /**
41
     * @var array
42
     */
43
    protected $reels;
44
45
    /**
46
     * @var Request
47
     */
48
    protected $request;
49
50
    /**
51
     * @var array
52
     */
53
    protected $delimiter = array('{', '}');
54
55
    /**
56
     * @var integer
57
     */
58
    protected $undefinedCardResolution = UndefinedCardResolution::DEFAULT_CARD;
59
60
    const NOT_SET_PARAMETER = "not_set";
61
62
    /**
63
     * @param array         $config   The SlotMachine configuration data
64
     * @param Request|null  $request  The Request object
65
     */
66
    public function __construct(array $config = array(), Request $request = null)
67
    {
68
        parent::__construct();
69
70
        $this->config = $config;
71
        $this->request = !is_null($request) ? $request : Request::createFromGlobals();
72
73
        $this->initialize();
74
    }
75
76
    /**
77
     * Set up the SlotMachine in a ready to use state
78
     */
79
    private function initialize()
80
    {
81
        $this->undefinedCardResolution = isset($this->config['options']['undefined_card'])
82
            ? static::translateUndefinedCardResolution($this->config['options']['undefined_card'])
83
            : UndefinedCardResolution::DEFAULT_CARD;
84
85
        if (isset($this->config['options']['delimiter'])) {
86
            $this->delimiter = $this->config['options']['delimiter'];
87
        }
88
89
        foreach ($this->config['slots'] as $slotName => &$slotData) {
90
            $slotData['name'] = $slotName;
91
92
            if (is_string($slotData['reel'])) {
93
                $slotData['reel'] = $this->config['reels'][$slotData['reel']];
94
            }
95
96
            if (!isset($slotData['nested'])) {
97
                $slotData['nested'] = array();
98
            }
99
100
            $slotData['undefined_card'] = (!isset($slotData['undefined_card']))
101
                ? $this->undefinedCardResolution
102
                : static::translateUndefinedCardResolution($slotData['undefined_card']);
103
104
            $this->offsetSet($slotName, function () use ($slotData) {
105
                return new Slot($slotData);
106
            });
107
        }
108
    }
109
110
    /**
111
     * @param string $option  The name of the constant
112
     *
113
     * @return integer
114
     *
115
     * @throws \InvalidArgumentException
116
     */
117
    public static function translateUndefinedCardResolution($option)
118
    {
119
        if (defined($setting = '\\SlotMachine\\UndefinedCardResolution::' . $option)) {
120
            return constant($setting);
121
        }
122
123
        throw new \InvalidArgumentException($setting . ' is not a valid option');
124
    }
125
126
    /**
127
     * Interpolates cards values into the cards nested slot placeholders.
128
     * Based on the example given in the PSR-3 specification.
129
     *
130
     * @link https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md PSR-3 specification
131
     * @param string $card
132
     * @param array  $nestedCards
133
     * @param array  $delimiter
134
     * @throws \LengthException if less than two delimiter tokens are giving.
135
     * @return string
136
     */
137
    public static function interpolate($card, array $nestedCards = array(), array $delimiter = array('{', '}'))
138
    {
139
        if (2 > $tokens = count($delimiter)) {
140
            throw new \LengthException('Number of delimiter tokens too short. Method requires exactly 2.');
141
        }
142
143
        // SlotMachine can still function with more than two delimiter tokens,
144
        // but will generate a warning.
145
        if ($tokens > 2) {
146
            trigger_error('Too many delimiter tokens given', E_USER_WARNING);
147
        }
148
149
        // build a replacement array with braces around the context keys
150
        $replace = array();
151
        foreach ($nestedCards as $slot => $nestedCard) {
152
          $replace[$delimiter[0] . $slot . $delimiter[1]] = $nestedCard;
153
        }
154
155
        // interpolate replacement values into the message and return
156
        return strtr($card, $replace);
157
    }
158
159
    /**
160
     * @param string  $slot
161
     * @param integer $default
162
     * @return string
163
     */
164
    public function get($slot, $default = null)
165
    {
166
        // Resolve default index. The one passed to the second augument will
167
        // take presidence, followed by the slot's default index.
168
169
        // Check if the slot's default value has been set and the method's
170
        // default value is empty
171
        if (!is_null($slotDefault = $this->offsetGet($slot)->getDefaultIndex()) && is_null($default)) {
172
            $default = $slotDefault;
173
        }
174
175
        // If default has not be set in the slot or the method, use 0.
176
        if (is_null($default)) {
177
            $default = 0;
178
        }
179
180
        // If no nested slots, return the card as is.
181
        if (0 === count($nested = $this->offsetGet($slot)->getNested())) {
182
            return $this->offsetGet($slot)->getCard($this->resolveIndex($slot, $default));
183
        }
184
185
        // Resolve Nested Slots
186
        $nestedCards = array();
187
188
        // Get the cards of the nested slots
189
        foreach ($nested as $nestedSlot) {
190
            $nestedCards[$nestedSlot] = $this->offsetGet($nestedSlot)->getCard(
191
                $this->resolveIndex($nestedSlot, $this->offsetGet($nestedSlot)->getDefaultIndex())
192
            );
193
        }
194
195
        // Translate the placeholders in the parent card.
196
        return static::interpolate(
197
            $this->offsetGet($slot)->getCard($this->resolveIndex($slot, $default)),
198
            $nestedCards,
199
            $this->delimiter
200
        );
201
    }
202
203
    /**
204
     * @param string  $slot
205
     * @param integer $default
206
     * @return integer
207
     */
208
    protected function resolveIndex($slot, $default = 0)
209
    {
210
        $keyWithSetValue = false;
211
        $slotKeys = $this->offsetGet($slot)->getKeys();
212
213
        // Perform a dry-run to find out if a value has been set, if it hasn't
214
        // then assign a string. The `has()` method for the Request's `query`
215
        // property won't work recursively for array parameters.
216
        foreach ($slotKeys as $key) {
217
            $dry = $this->request->query->get($key, static::NOT_SET_PARAMETER, true);
0 ignored issues
show
Unused Code introduced by
The call to ParameterBag::get() has too many arguments starting with true.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
218
            if (static::NOT_SET_PARAMETER !== $dry) {
219
                $keyWithSetValue = $key;
220
                break;
221
            }
222
        }
223
224
        // If a key was not set a value, return the default value of the first key assigned to the slot.
225
        return $this->request->query->getInt(($keyWithSetValue ?: $slotKeys[0]), $default, true);
0 ignored issues
show
Unused Code introduced by
The call to ParameterBag::getInt() has too many arguments starting with true.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
226
    }
227
228
    /**
229
     * @param Request $request
230
     */
231
    public function setRequest(Request $request)
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
232
    {
233
        $this->request = $request;
234
    }
235
236
    /**
237
     * @return Request
238
     */
239
    public function getRequest()
240
    {
241
        return $this->request;
242
    }
243
244
    /**
245
     * @return array
246
     */
247
    public function getConfig()
248
    {
249
        return $this->config;
250
    }
251
252
    /**
253
     * The number of Slots in the machine
254
     *
255
     * @return integer
256
     */
257
    public function count()
258
    {
259
        $c = 0;
260
        // Using Pimple::$values will return the Closures, so instead get the
261
        // values in the container via ArrayAccess.
262
        foreach ($this->keys() as $valueName) {
263
            if ($this[$valueName] instanceof Slot) {
264
                ++$c;
265
            }
266
        }
267
        return $c;
268
    }
269
270
    /**
271
     * Return all the slots.
272
     *
273
     * @return array
274
     */
275
    public function all()
276
    {
277
        $all = array();
278
279
        // Pimple::keys()
280
        foreach ($this->keys() as $slotName) {
281
            $all[$slotName] = $this->get($slotName);
282
        }
283
284
        return $all;
285
    }
286
287
    /**
288
     * Export current values for all slots in JSON format.
289
     *
290
     * @return string
291
     */
292
    public function toJson()
293
    {
294
        return json_encode($this->all());
295
    }
296
297
    /**
298
     * Export to JSON by treating the object as a string.
299
     *
300
     * @return string
301
     */
302
    public function __toString()
303
    {
304
        return $this->toJson();
305
    }
306
}
307