Passed
Push — master ( 3dd71e...2a510c )
by Richard
03:38
created

Report::custom_config_value()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
ccs 3
cts 4
cp 0.75
cc 2
eloc 4
nc 2
nop 2
crap 2.0625
1
<?php
2
3
namespace Lechimp\Dicto\Report;
4
5
/**
6
 * Base class for reports.
7
 */
8
abstract class Report {
9
    /**
10
     * @var Config
11
     */
12
    protected $config;
13
14
    /**
15
     * @var Queries 
16
     */
17
    protected $queries;
18
19 2
    public function __construct(Queries $queries, Config $config) {
20 2
        $this->queries = $queries;
21 2
        $this->config = $config;
22 2
    }
23
24
    /**
25
     * Get the default template for the report.
26
     *
27
     * This could be:
28
     *   - a filename, which is then assumed to be in templates-directory of
29
     *     dicto or in the current working directory, if not found in dicto
30
     *     templates
31
     *   - an absolute path
32
     *
33
     * @return string
34
     */
35
    abstract protected function default_template();
36
37
    /**
38
     * Get the name of the template.
39
     *
40
     * Uses config["template"] or falls back to default template.
41
     *
42
     * @return string
43
     */
44 3
    protected function template() {
45 3
        return $this->custom_config_value("template", $this->default_template());
46
    }
47
48
    /**
49
     * Get the absolute path for a template.
50
     *
51
     * Does only realpath(..) if an absolute path is given. Searches dicto-templates
52
     * directory, config-directory and current working directory otherwise.
53
     *
54
     * @throws  \InvalidArgumentException if none of the strategies leads to an
55
     *                                    existing file.
56
     * @param   string  $name
57
     * @return  string
58
     */
59 4
    protected function template_path($name) {
60 4
        $path = $name;
61 4
        if (substr($name, 0, 1) !== "/") {
62
            $candidates =
63 2
                [ __DIR__."/../../templates/{$name}.php"
64 2
                , __DIR__."/../../templates/{$name}"
65 2
                , $this->config->path()."/{$name}"
66 2
                ];
67 2
            foreach ($candidates as $candidate) {
68 2
                if (file_exists($candidate)) {
69 2
                    $path = $candidate;
70 2
                    break;
71
                }
72 2
            }
73 2
        }
74 4
        if (!file_exists($path)) {
75 1
            throw new \InvalidArgumentException("Can't find path to template '$name'.");
76
        }
77 4
        return realpath($path);
78
    }
79
80
    /**
81
     * Load a template from a path.
82
     *
83
     * Expects the file to contain a function with the same name as the file
84
     * (minus postfix) prefixed with template_, that writes to stdout.
85
     *
86
     * @param   string  $template_path
87
     * @return  \Closure    array -> null
88
     */
89 3
    protected function load_template($template_path) {
90 3
        $tpl_fct_name = $this->template_function_name($template_path);
91 3
        require_once($template_path);
92 3
        return function (array $report) use ($tpl_fct_name) {
93 3
            ob_start();
94 3
            $tpl_fct_name($report);
95 3
            return ob_get_clean();
96 3
        };
97
    }
98
99
    /**
100
     * Derive the name of the template function from a filename.
101
     *
102
     * @param   string  $path
103
     * @return  string
104
     */
105 4
    protected function template_function_name($path) {
106 4
        $matches = [];
107 4
        if (!preg_match("%(.*/)?([^./]+)[.]php%i", $path, $matches)) {
108
            throw new \RuntimeException("Path '$path' seems not to point to a template.");
109
        }
110 4
        return "template_".$matches[2];
111
    }
112
113
    /**
114
     * Generate the report.
115
     *
116
     * Should return a structured array containing the information in the report.
117
     *
118
     * @return array 
119
     */
120
    abstract public function generate();
121
122
    /**
123
     * Write the report to some handle using a template.
124
     *
125
     * @param   resource    $handle
126
     * @return  null
127
     */
128 3
    public function write($handle) {
129 3
        assert('is_resource($handle)');
130 3
        $template_path = $this->template_path($this->template());
131 3
        $template = $this->load_template($template_path);
132 3
        $report = $this->generate();
133 3
        $printed_report = $template($report);
134 3
        fputs($handle, $printed_report);
135 3
    }
136
137
    /**
138
     * Get value from the custom config or default if it does not exist.
139
     *
140
     * @param   string      $key
141
     * @param   mixed       $default
142
     * @return  mixed
143
     */
144 3
    protected function custom_config_value($key, $default) {
145 3
        if (isset($this->config->config()[$key])) {
146
            return $this->config->config()[$key];
147
        }
148 3
        return $default;
149
    }
150
}
151