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.
Completed
Push — develop ( 02ca20...e56151 )
by Rolf
03:10
created

Utils::checkCallable()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 1
cts 1
cp 1
rs 9.6666
cc 3
eloc 6
nc 2
nop 4
crap 3
1
<?php
2
namespace izzum\statemachine\utils;
3
use izzum\command\NullCommand;
4
use izzum\command\Composite;
5
use izzum\statemachine\Exception;
6
use izzum\statemachine\Context;
7
use izzum\command\ICommand;
8
use izzum\statemachine\State;
9
use izzum\statemachine\StateMachine;
10
use izzum\statemachine\Transition;
11
12
/**
13
 * utils class that has some helper methods for diverse purposes
14
 *
15
 * @author Rolf Vreijdenberger
16
 *
17
 */
18
class Utils {
19
    const STATE_CONCATENATOR = '_to_';
20
21
22
    /**
23
     * Checks a fully loaded statemachine for a valid configuration.
24
     *
25
     * This is useful in a debug situation so you can check for the validity of
26
     * rules, commands and callables in guard logic, transition logic and state entry/exit logic
27
     * before they hit a
28
     *
29
     * This does not instantiate any objects. It just checks if callables can be found
30
     * and if classes for rules and commands can be found
31 64
     *
32
     * @param StateMachine $machine
33 64
     * @return Exception[] an array of exceptions if anything is wrong with the configuration
34
     */
35
    public static function checkConfiguration(StateMachine $machine)
36
    {
37
38
        //TODO: also check the rules and commands
39
40
        $exceptions = array();
41
        $output = array();
42
        //check state callables
43
        foreach($machine->getStates() as $state)
44
        {
45
            $exceptions[] = self::getExceptionForCheckingCallable($state->getExitCallable(), State::CALLABLE_ENTRY, $state);
46
            $exceptions[] = self::getExceptionForCheckingCallable($state->getEntryCallable(), State::CALLABLE_ENTRY, $state);
47
        }
48
49
        //check transition callables
50
        foreach($machine->getTransitions() as $transition)
51 39
        {
52
            $exceptions[] = self::getExceptionForCheckingCallable($transition->getGuardCallable(), Transition::CALLABLE_GUARD, $transition);
53
            $exceptions[] = self::getExceptionForCheckingCallable($transition->getTransitionCallable(), Transition::CALLABLE_TRANSITION, $transition);
54
        }
55
        //get the exceptions
56
        foreach($exceptions as $e)
57
        {
58 39
            if(is_a($e, '\Exception')){
59
                $output[] = $e;
60 26
            }
61
        }
62
        return $output;
63 26
    }
64
65
    /**
66
     * @param callable $callable
67 26
     * @param string $type a type description of the callable eg: State::CALLABLE_ENTRY
68
     * @param string $info extra info for exception message purposes
69
     * @param Context $context optional: the context the callable is called in
70 26
     * @return Exception if the callable does not pass the check
71
     */
72 26
    private static function getExceptionForCheckingCallable($callable, $type, $info, $context = null)
73 26
    {
74 3
        try {
75 3
            self::checkCallable($callable, $type, $info, $context);
76
        } catch(\Exception $e) {
77
            return $e;
78
        }
79 23
        return null;
80 21
    }
81 23
82 2
83 2
    /**
84
     * @param callable $callable
85 21
     * @param string $type a type description of the callable eg: State::CALLABLE_ENTRY
86 21
     * @param string $info extra info for exception message purposes
87
     * @param Context $context optional: the context the callable is called in
88
     * @return bool
89
     * @throws Exception if the callable does not pass the check
90
     */
91
    public static function checkCallable($callable, $type, $info, $context = null)
92
    {
93
        if($callable !== null && !is_callable($callable)) {
94
            throw new Exception(sprintf("not a valid '%s' callable for '%s'. %s",
95
                $type, $info, $context ),
96
                Exception::CALLABLE_FAILURE);
97
        }
98
        return true;
99 4
    }
100
    
101 4
    
102
    /**
103 2
     * gets the transition name by two state names, using the default convention
104 2
     * for a transition name (which is concatenating state-from to state-to with
105 4
     * '_to_')
106 1
     *
107
     * @param string $from
108 3
     *            the state from which the transition is made
109
     * @param string $to
110
     *            the state to which the transition will be made
111
     * @return string <state_from>_to_<state_to>
112
     */
113
    public static function getTransitionName($from, $to)
114
    {
115
        return $from . self::STATE_CONCATENATOR . $to;
116
    }
117
118
    /**
119
     * returns the associated Command for the entry/exit/transition action on a
120
     * State or a Transition.
121
     * the Command will be configured with the 'reference' of the stateful
122
     * object
123
     *
124
     * @param string $command_name
125 41
     *            entry~,exit~ or transition command name.
126
     *            multiple commands can be split by a ',' in which case a
127 41
     *            composite command will be returned.
128 41
     * @param Context $context
129
     *            to be able to get the entity
130 19
     * @return ICommand
131 19
     * @throws Exception
132 19
     */
133 19
    public static function getCommand($command_name, Context $context)
134 19
    {
135 19
        // it's oke to have no command, as there might be 'marker' states, where
136 37
        // we just need to transition something to a next state (according to a
137
        // rule)
138 41
        // where useful work can be done (eg: from the 'initial' type state to
139
        // a 'shortcut' state for special cases.
140
        if ($command_name === '' || $command_name === null) {
141
            // return a command without side effects
142
            return new NullCommand();
143
        }
144
145
        $output = new Composite();
146
147
        // a command string can be made up of multiple commands seperated by a
148
        // comma
149
        $all_commands = explode(',', $command_name);
150
151
        // get the correct object to inject in the command(s)
152 20
        $entity = $context->getEntity();
153
154 20
        foreach ($all_commands as $single_command) {
155 20
            if (!class_exists($single_command)) {
156 20
                $e = new Exception(sprintf("failed command creation, class does not exist: (%s) for Context (%s)", $single_command, $context->toString()), Exception::COMMAND_CREATION_FAILURE);
157 20
                throw $e;
158 20
            }
159 20
160 1
            try {
161 1
                $command = new $single_command($entity);
162 1
                $output->add($command);
163 20
            } catch(\Exception $e) {
164
                $e = new Exception(sprintf("command (%s) objects to construction for Context (%s). message: '%s'", $single_command, $context->toString(), $e->getMessage()), Exception::COMMAND_CREATION_FAILURE);
165
                throw $e;
166
            }
167
        }
168
        return $output;
169
    }
170
171
    /**
172
     * Always returns an izzum exception (converts a non-izzum exception to an
173
     * izzum exception).
174
     * optionally throws it.
175
     *
176
     * @param \Exception $e
177
     * @param int $code
178
     * @return Exception
179
     * @throws Exception
180
     */
181
    public static function wrapToStateMachineException(\Exception $e, $code, $throw = false)
182
    {
183
        if (!is_a($e, 'izzum\statemachine\Exception')) {
184
            // wrap the exception and use the code provided.
185
            $e = new Exception($e->getMessage(), $code, $e);
186
        }
187
        if ($throw) {
188
            throw $e;
189
        }
190
        return $e;
191
    }
192
193
    /**
194
     * get all states that match a possible regex state from the set of states
195
     * provided
196
     *
197
     * @param State $regex
198
     *            a possible regex state.
199
     * @param State[] $targets
200
     *            all target State instances that we check the regex against.
201
     * @return State[] an array of State instances from the $targets State
202
     *         instances that matched the (negated) regex, or the $regex State if it was
203
     *         not a regex State after all.
204
     * @link https://php.net/manual/en/function.preg-match.php
205
     * @link http://regexr.com/ for trying out regular expressions
206
     */
207
    public static function getAllRegexMatchingStates(State $regex, $targets)
208
    {
209
        $all = array();
210
        if ($regex->isRegex()) {
211
            // lookup all from states that conform to this rgex
212
            foreach ($targets as $target) {
213
                if (!$target->isRegex() && self::matchesRegex($regex, $target)) {
214
                    $all [] = $target;
215
                }
216
            }
217
        } else {
218
            $all [] = $regex;
219
        }
220
        return $all;
221
    }
222
223
    /**
224
     * does an input regex state match a target states' name?
225
     *
226
     * @param State $regex
227
     *            the regex state
228
     * @param State $target
229
     *            the state to match the regular expression to
230
     * @return boolean
231
     * @link https://php.net/manual/en/function.preg-match.php
232
     * @link http://regexr.com/ for trying out regular expressions
233
     */
234
    public static function matchesRegex(State $regex, State $target)
235
    {
236
        $matches = false;
237
        if ($regex->isNormalRegex()) {
238
            $expression = str_replace(State::REGEX_PREFIX, '', $regex->getName());
239
            $matches = preg_match($expression, $target->getName()) === 1;
240
        }
241
        if($regex->isNegatedRegex()) {
242
            $expression = str_replace(State::REGEX_PREFIX_NEGATED, '', $regex->getName());
243
            $matches = preg_match($expression, $target->getName()) !== 1;
244
        }
245
        return $matches;
246
    }
247
}