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.

JSON   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 6
dl 0
loc 108
ccs 49
cts 49
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A createFromFile() 0 12 3
A getJSON() 0 4 1
A getJSONSchema() 0 5 1
C load() 0 45 8
A toString() 0 4 1
A __toString() 0 4 1
1
<?php
2
namespace izzum\statemachine\loader;
3
use izzum\statemachine\loader\Loader;
4
use izzum\statemachine\StateMachine;
5
use izzum\statemachine\State;
6
use izzum\statemachine\Transition;
7
use izzum\statemachine\Exception;
8
9
/**
10
 * JSON loader. accepts a json string and loads a machine from it.
11
 * The json string can contain one or more machine definitions. 
12
 * The correct machine will be found from the json structure.
13
 * 
14
 * This class provides a way to load json from a file on your file system (fast access)
15
 * and is also used by the Redis adapter to load a json string from a redis server.
16
 * 
17
 * The format of the data to be loaded is specified via a json-schema. 
18
 * The schema can be retrieved via JSON::getJSONSchema() and the schema itself and 
19
 * a full example of the data can be found in 'assets/json'
20
 * 
21
 * @link https://en.wikipedia.org/wiki/JSON
22
 * @Link http://json-schema.org
23
 * @link http://jsonschemalint.com/draft4/ for validating according to a json-schema (useful for building your own)
24
 * @link https://php.net/manual/en/function.json-decode.php
25
 * @link https://php.net/manual/en/function.file-get-contents.php
26
 * @author Rolf Vreijdenberger
27
 *
28
 */
29
class JSON implements Loader {
30
    /**
31
     * an undecoded json string
32
     * @var string
33
     */
34
    private $json;
35
36
    /**
37
     * 
38
     * @param string $json optional a valid json string according to the schema
39
     */
40 9
    public function __construct($json)
41
    {
42 9
        $this->json = $json;
43 9
    }
44
45
    /**
46
     * creates an instance of this class with the data loaded from a file.
47
     * @param string $filename eg: __DIR__ . '/../../configuration.json'
48
     * @return JSON an instance of JSON with the data read from the file
49
     * @throws Exception
50
     */
51 6
    public static function createFromFile($filename)
52
    {
53 6
        if (!file_exists($filename)) {
54 1
            throw new Exception(sprintf('Failed to load json from file %s. The file does not exist', $filename), Exception::BAD_LOADERDATA);
55
        }
56
        //suppres warning with @ operator. we are explicitely testing the return value.
57 5
        $json = @file_get_contents($filename);
58 5
        if (false === $json) {
59 1
            throw new Exception(sprintf('Failed to read json data from file %s. Unknown error (permissions?)', $filename), Exception::BAD_LOADERDATA);
60
        }
61 4
        return new static($json);
62
    }
63 9
    public function getJSON()
64
    {
65 9
        return $this->json;
66
    }
67
68
    /**
69
     * gets the json schema used for the datastructure of the statemachine definitions
70
     * @return string
71
     */
72 1
    public function getJSONSchema()
73
    {
74 1
        $schema = '{"$schema":"http://json-schema.org/draft-04/schema#","type":"object","title":"izzum statemachines definitions schema","description":"This is a json-schema for the statemachines as defined by the php izzum library. see http://jsonschemalint.com/draft4/# to validate your json definitions","required":["machines"],"properties":{"comment":{"type":["string","null"],"description":"comments for the description of the file contents can be placed here."},"machines":{"minItems":1,"uniqueItems":true,"type":"array","description":"All machines are defined here","items":{"required":["name","description","states","transitions"],"type":"object","description":"A full machine definition","properties":{"name":{"type":"string","description":"the name of the machine","pattern":"^([a-z0-9])+((-)?([a-z0-9])+)*$"},"factory":{"type":["string","null"],"description":"\\fully\\qualified\\Factory class name"},"description":{"type":["string","null"],"description":"a description of the machine"},"states":{"type":"array","description":"All state definitions for a machine go in this array","minItems":2,"uniqueItems":true,"items":{"type":"object","description":"A state definition","required":["name","type"],"properties":{"name":{"type":"string","description":"the state name","pattern":"^([a-z0-9])+((-)?([a-z0-9])+)*$|^(not-)?regex:(.*)$"},"type":{"enum":["initial","normal","final","regex"],"description":"the type of state: initial (1), normal(0..n), final (1..n) or regex (0..n)"},"entry_command":{"type":["string","null"],"description":"\\fully\\qualified\\Command (multiple can be comma seperated) that will be executed on entry of the state"},"exit_command":{"type":["string","null"],"description":"\\fully\\qualified\\Command name (multiple can be comma seperated) that will be executed on exit of the state"},"entry_callable":{"type":["string","null"],"description":"A php callable for state entry. can only be in form of fully\\qualified\\Class::staticMethod"},"exit_callable":{"type":["string","null"],"description":"A php callable for state exit. can only be in form of fully\\qualified\\Class::staticMethod"},"description":{"type":["string","null"],"description":"A description of the state"}}}},"transitions":{"type":"array","description":"A list of transitions, referring to the states","minItems":1,"uniqueItems":true,"items":{"type":"object","description":"A transition definition","required":["state_from","state_to","event"],"properties":{"state_from":{"type":"string","description":"the state from which the transition is made. this can be a regex.","pattern":"^([a-z0-9])+((-)?([a-z0-9])+)*$|^(not-)?regex:(.*)$"},"state_to":{"type":"string","description":"the state to which the transition is made. this can be a regex.","pattern":"^([a-z0-9])+((-)?([a-z0-9])+)*$|^(not-)?regex:(.*)$"},"event":{"type":["string","null"],"description":"an event name by which you can call this transition","pattern":"^[a-zA-Z0-9]+$"},"rule":{"type":["string","null"],"description":"\\fully\\qualified\\Rule name (multiple can be comma seperated) that will be checked as boolean guard logic before the transition"},"command":{"type":["string","null"],"description":"\\fully\\qualified\\Command name (multiple can be comma seperated) that will be executed as the transition logic"},"guard_callable":{"type":["string","null"],"description":"A php callable for guard logic. can only be in form of fully\\qualified\\Class::staticMethod"},"transition_callable":{"type":["string","null"],"description":"A php callable for transition logic. can only be in form of fully\\qualified\\Class::staticMethod"},"description":{"type":["string","null"],"description":"The description of the transition"}}}}}}}}}';
75 1
        return $schema;
76
    }
77
78
    /**
79
     * {@inheritDoc}
80
     */
81 9
    public function load(StateMachine $stateMachine)
82
    {
83
        //decode the json in a php object structure
84 9
        $decoded = json_decode($this->getJSON(), false);
85 9
        if (!$decoded) {
86
            //could not decode (make sure that fully qualified names are escaped with 
87
            //2 backslashes: \\izzum\\commands\\NullCommand and that only double quotes are used.
88 1
            throw new Exception(sprintf('could not decode json data. did you only use double quotes? check the json format against %s', 'http://jsonlint.com/'), Exception::BAD_LOADERDATA);
89
        }
90 8
        $name = $stateMachine->getContext()->getMachine();
91 8
        $found = false;
92 8
        $data = null;
93 8
        if(is_array(@$decoded->machines)) {
94 7
            foreach ($decoded->machines as $data) {
95 7
                if ($data->name === $name) {
96 7
                    $found = true;
97 7
                    break;
98
                }
99 7
            }
100 7
        }
101 8
        if (!$found) {
102
            //no name match found
103 1
            throw new Exception(sprintf('no machine data found for %s in json. seems like a wrong configuration.', $name), Exception::BAD_LOADERDATA);
104
        }
105
        //accessing json as an object with an @ error suppresion operator ('shut the fuck up' operator),
106
        //allows you to get properties, even if they do not exist, without notices.
107
        //this lets us be a little lazy in mapping the json properties to the state and transition properties
108 7
        $states = array();
109 7
        foreach ($data->states as $state) {
110 7
            $tmp = new State($state->name, $state->type, @$state->entry_command, @$state->exit_command, @$state->entry_callable, @$state->exit_callable);
111 7
            $tmp->setDescription(@$state->description);
112 7
            $states [$tmp->getName()] = $tmp;
113 7
        }
114
        
115 7
        $transitions = array();
116 7
        foreach ($data->transitions as $transition) {
117 7
            $tmp = new Transition($states [$transition->state_from], $states [$transition->state_to], @$transition->event, @$transition->rule, @$transition->command, @$transition->guard_callable, @$transition->transition_callable);
118 7
            $tmp->setDescription(@$transition->description);
119 7
            $transitions [] = $tmp;
120 7
        }
121
        
122
        //delegate to loader
123 7
        $loader = new LoaderArray($transitions);
124 7
        return $loader->load($stateMachine);
125
    }
126
127 1
    public function toString()
128
    {
129 1
        return get_class($this);
130
    }
131
    
132 1
    public function __toString()
133
    {
134 1
        return $this->toString();
135
    }
136
}
137
138