Completed
Push — master ( 774eb2...689ba3 )
by Richard
07:00
created

App::create_dic()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 63
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 63
rs 9.4347
cc 2
eloc 39
nc 2
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 * 
5
 * Copyright (c) 2016 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received 
8
 * a copy of the licence along with the code.
9
 */
10
11
namespace Lechimp\Dicto\App;
12
13
use Lechimp\Dicto\App\RuleLoader;
14
15
use Symfony\Component\Yaml\Yaml;
16
use Pimple\Container;
17
use PhpParser\ParserFactory;
18
use Doctrine\DBAL\DriverManager;
19
20
/**
21
 * The App to be run from a script.
22
 */
23
class App {
24
    /**
25
     * @var Container
26
     */
27
    protected $dic;
28
29
    public function __construct(\Closure $postprocess_dic = null) {
30
        ini_set('xdebug.max_nesting_level', 200);
31
32
        if ($postprocess_dic === null) {
33
            $postprocess_dic = function($c) { return $c; };
34
        }
35
        $this->dic = $this->create_dic($postprocess_dic); 
36
    }
37
38
    /**
39
     * Run the app.
40
     *
41
     * @param   array   $params     from commandline
42
     * @return  null
43
     */
44
    public function run(array $params) {
45
        if (count($params) < 2) {
46
            throw new \RuntimeException(
47
                "Expected path to rule-file as first parameter.");
48
        }
49
50
        $configs = array();
51
        list($ruleset, $configs[]) = $this->load_rules_file($params[1]);
52
53
        // drop programm name and rule file path
54
        array_shift($params);
55
        array_shift($params);
56
57
        $this->load_extra_configs($params, $configs);
58
59
        $this->dic["config"] = $this->create_config($configs);
60
        $this->dic["ruleset"] = $ruleset;
61
        $this->dic["engine"]->run();
62
    }
63
64
    /**
65
     * Load rules and initial config from a *.php-file.
66
     *
67
     * @param   string  $path
68
     * @return  array   ($ruleset, $config)
69
     */
70
    protected function load_rules_file($path) {
71
        if (!file_exists($path)) {
72
            throw new \RuntimeException("Unknown rule-file '$path'");
73
        }
74
        $rule_loader = $this->dic["rule_loader"];
75
        list($ruleset, $config) = $rule_loader->load_rules_from($path);
76
        assert('is_array($config)');
77
        assert('$ruleset instanceof \\Lechimp\\Dicto\\Definition\\RuleSet');
78
        return array($ruleset, $config);
79
    }
80
81
    /**
82
     * Load extra configs from yaml files.
83
     *
84
     * @param   array   $config_file_paths
85
     * @param   &array  $configs_array
0 ignored issues
show
Documentation introduced by
The doc-type &array could not be parsed: Unknown type name "&array" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
86
     * @return  null
87
     */
88
    protected function load_extra_configs(array $config_file_paths, array &$configs_array) {
0 ignored issues
show
Unused Code introduced by
The parameter $configs_array is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
89
        foreach ($config_file_paths as $config_file) {
90
            if (!file_exists($config_file)) {
91
                throw new \RuntimeException("Unknown config-file '$config_file'");
92
            }
93
            $configs[] = Yaml::parse(file_get_contents($config_file));
0 ignored issues
show
Coding Style Comprehensibility introduced by
$configs was never initialized. Although not strictly required by PHP, it is generally a good practice to add $configs = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
94
        }
95
    }
96
97
    /**
98
     * Create a validated config from arrays containing config chunks.
99
     *
100
     * @param   array[] $configs
101
     * @return  Config
102
     */
103
    protected function create_config(array $configs) {
104
        return new Config($configs);
105
    }
106
107
    /**
108
     * Create and initialize the DI-container.
109
     *
110
     * @param   \Closure    $postprocess_dic    Closure to postprocess the DI.
111
     * @return  Container
112
     */
113
    protected function create_dic(\Closure $postprocess_dic) {
114
        $container = new Container();
115
116
        $container["rule_loader"] = function($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
117
            return new RuleLoader();
118
        };
119
120
        $container["engine"] = function($c) {
121
            return new Engine
122
                ( $c["config"]
123
                , $c["indexer"]
124
                , $c["analyzer"]
125
                );
126
        };
127
128
        $container["indexer"] = function($c) {
129
            return new \Lechimp\Dicto\Indexer\Indexer
130
                ( $c["php_parser"]
131
                , $c["config"]->project_root()
132
                , $c["database"]
133
                );
134
        };
135
136
        $container["php_parser"] = function($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
137
            return (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
138
        };
139
140
        $container["database"] = function($c) {
141
            $db = new DB($c["connection"]);
142
            $db->init_sqlite_regexp();
143
            $db->maybe_init_database_schema();
144
            return $db;
145
        };
146
147
        $container["connection"] = function($c) {
148
            return DriverManager::getConnection
149
                ( array
150
                    ( "driver" => "pdo_sqlite"
151
                    , "memory" => $c["config"]->sqlite_memory()
152
                    , "path" => $c["config"]->sqlite_path()
153
                    )
154
                );
155
        };
156
157
        $container["analyzer"] = function($c) {
158
            return new \Lechimp\Dicto\Analysis\Analyzer
159
                ( $c["ruleset"]
160
                , $c["database"]
161
                , $c["report_generator"]
162
                );
163
        };
164
165
        $container["report_generator"] = function($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
166
            return new CLIReportGenerator();
167
        };
168
169
        $container = $postprocess_dic($container);
170
        if (!($container instanceof Container)) {
171
            throw new \RuntimeException
172
                ("DIC postprocessor did not return a Container.");
173
        }
174
        return $container;
175
    }
176
}
177