Completed
Push — master ( 86b2cd...b16d12 )
by Richard
03:26
created

Generator   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 102
rs 10
c 0
b 0
f 0
wmc 14
lcom 1
cbo 2

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A generate() 0 7 1
A maybe_load_source() 0 9 3
A build_report() 0 12 3
A open_handle() 0 7 2
A fully_qualified_class_name() 0 14 4
1
<?php
2
3
namespace Lechimp\Dicto\Report;
4
5
/**
6
 * Generates reports from configs.
7
 */
8
class Generator {
9
    /**
10
     * @var Queries
11
     */
12
    protected $queries;
13
14
    public function __construct(Queries $queries) {
15
        $this->queries = $queries;
16
    }
17
18
    /**
19
     * Generate a report according to config.
20
     *
21
     * @param   Config
22
     * @return  null
23
     */
24
    public function generate(Config $config) {
25
        $this->maybe_load_source($config->source_path());
26
        $report = $this->build_report($config);
27
        $handle = $this->open_handle($config->target());
28
        $report->write($handle);
29
        fclose($handle);
30
    }
31
32
    /**
33
     * Load source for report if required.
34
     *
35
     * @param   string|null $path
36
     * @return  null
37
     */
38
    protected function maybe_load_source($path) {
39
        if ($path === null) {
40
            return;
41
        }
42
        if (!file_exists($path)) {
43
            throw new \RuntimeException("Could not load non-existing file '$path'.");
44
        }
45
        require_once($path);
46
    }
47
48
    /**
49
     * Build a report instance.
50
     *
51
     * @param   Config  $config
52
     * @throws  \RuntimeException if no corresponding class was found.
53
     * @throws  \RuntimeException if given class does not inherit from namespace.
54
     * @return  Report
55
     */
56
    protected function build_report($config) {
57
        $class_name = $config->class_name();
58
        $fq_name = $this->fully_qualified_class_name($class_name);
59
        if (!class_exists($fq_name)) {
60
            throw new \RuntimeException("Class '$class_name' does not a exist.");
61
        }
62
        $report = new $fq_name($this->queries, $config);
63
        if (!is_subclass_of($report, Report::class)) {
1 ignored issue
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Lechimp\Dicto\Report\Report::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
64
            throw new \RuntimeException("'$class_name' is not a Report-class.");
65
        }
66
        return $report;
67
    }
68
69
    /**
70
     * Open a handle to write the report to.
71
     *
72
     * @param   string  $handle_name
73
     * @return  resource
74
     */
75
    protected function open_handle($handle_name) {
76
        $handle = fopen($handle_name, "w");
77
        if (!$handle) {
78
            throw new \RuntimeException("Could not open handle '$handle_name'.");
79
        }
80
        return $handle;
81
    }
82
83
    /**
84
     * Derive fully qualified class name from the provided class name.
85
     *
86
     * If the class name starts with an "\" it is considered already fully
87
     * qualified.
88
     * If not, we check if $nameReport is found in \Lechimp\Dicto\Report
89
     * namespace or if $name is found in said namespace.
90
     * If that is also not the case, we assume the class is in the global
91
     * namespace.
92
     *
93
     * @return  string
94
     */
95
    protected function fully_qualified_class_name($name) {
96
        if (substr($name, 0, 1) == "\\") {
97
            return $name;
98
        }
99
        $fq = "\\Lechimp\\Dicto\\Report\\{$name}Report";
100
        if (class_exists($fq)) {
101
            return $fq;
102
        }
103
        $fq = "\\Lechimp\\Dicto\\Report\\$name";
104
        if (class_exists($fq)) {
105
            return $fq;
106
        }
107
        return "\\$name";
108
    }
109
}
110