PhpOutlookSignature::prepare_script()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 9
rs 10
1
<?php
2
3
namespace Pforret\PhpOutlookSignature;
4
5
use Exception;
6
7
class PhpOutlookSignature
8
{
9
    private string $default_template = '';
10
    private string $template_folder = '';    //<template>
11
    private string $template_file = '';      //<template>/<message>.htm
12
    private string $assets_folder = '';      //<template>/<message>_files/
13
    private string $assets_local = '';       //<message>_files
14
    private array $keywords = [];
15
    private array $included_files = [];
16
    private bool $is_ready = false;
17
18
    public function __construct(string $folder = '')
19
    {
20
        $this->is_ready = false;
21
        $this->default_template = __DIR__ . '/templates/default';
22
        if (!file_exists($this->default_template)) {
23
            throw new Exception(sprintf("Default template folder [%s] does not exist", $this->default_template));
24
        }
25
        if (!$folder) {
26
            $folder = $this->default_template;
27
        }
28
        if (!file_exists($folder)) {
29
            throw new Exception(sprintf("Template folder [%s] does not exist", $folder));
30
        }
31
        $this->template_folder = $folder;
32
        $this->check_template_files($this->template_folder);
33
        if (!file_exists($this->assets_folder."/filelist.xml")) {
34
            $this->create_filelist();
35
        }
36
        $this->analyze_template_text();
37
        $this->is_ready = true;
38
    }
39
40
    public function create(string $output_file, array $values, bool $ignore_errors = false): bool
41
    {
42
        $output_folder = dirname($output_file);
43
        $output_name = pathinfo($output_file, PATHINFO_FILENAME);
44
        $assets_folder_name = "${output_name}_files";
45
        $assets_folder = "$output_folder/$assets_folder_name";
46
        if (!file_exists($output_folder)) {
47
            mkdir($output_folder, 0777, true);
48
        }
49
        if (!file_exists($assets_folder)) {
50
            mkdir($assets_folder, 0777);
51
        }
52
        if (!isset($values['assets'])) {
53
            $values['assets'] = $assets_folder_name;
54
        }
55
        // fill in template
56
57
        $text = file_get_contents($this->template_file);
58
        foreach ($this->keywords as $keyword) {
59
            if (!$ignore_errors && !isset($values[$keyword])) {
60
                throw new Exception("Template expects [$keyword] but none was given");
61
            }
62
            $value = isset($values[$keyword]) ? $values[$keyword] : "";
63
            $text = str_replace('{' . $keyword . '}', $value, $text);
64
        }
65
        // save files
66
        file_put_contents($output_file, $text);
67
        foreach ($this->included_files as $file) {
68
            $file = str_replace('{assets}', $values['assets'], $file);
69
            $copy_file = "$assets_folder/" . basename($file);
70
            copy($file, $copy_file);
71
        }
72
        $this->prepare_script($this->template_folder.'/install_windows.cmd', $output_folder, '%APPDATA%\Microsoft\Signatures');
73
        // TODO: install script for MacOS
74
        return true;
75
    }
76
77
    // ---------------------------- PRIVATE METHODS
78
79
    private function prepare_script($input_file, $output_folder, $destination)
80
    {
81
        if (!file_exists($input_file)) {
82
            return false;
83
        }
84
        $install_script = $output_folder."/".basename($input_file);
85
        $script = file_get_contents($input_file);
86
        $script = str_replace('{destin}', $destination, $script);
87
        file_put_contents($install_script, $script);
88
    }
89
90
    private function check_template_files(string $folder): bool
91
    {
92
        $html_files = glob("$folder/*.htm");
93
        if (count($html_files) === 0) {
0 ignored issues
show
Bug introduced by
It seems like $html_files can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

93
        if (count(/** @scrutinizer ignore-type */ $html_files) === 0) {
Loading history...
94
            throw new Exception(sprintf("Template folder [%s] does not contain a .htm file", $this->template_folder));
95
        }
96
        if (count($html_files) > 1) {
97
            throw new Exception(sprintf("Template folder [%s] should only contain 1 .htm file (now: %d)", $this->template_folder, count($html_files)));
98
        }
99
100
        $this->template_file = $html_files[0];
101
        $template_name = basename($this->template_file, '.htm');
102
        $assets_folder = sprintf("%s/%s", $this->template_folder, "${template_name}_files");
103
        if (!is_dir($assets_folder)) {
104
            // TODO: look for alternative folder name in template
105
            throw new Exception(sprintf("Template assets folder [%s] cannot be found", $assets_folder));
106
            // most probable
107
        }
108
        $this->assets_folder = $assets_folder;
109
        $this->assets_local = basename($assets_folder);
110
111
        return true;
112
    }
113
114
    private function analyze_template_text(): bool
115
    {
116
        $this->keywords = [];
117
        $this->included_files = [];
118
        $text = file_get_contents($this->template_file);
119
        $text = str_replace($this->assets_local.'/', '{assets}/', $text);
120
        preg_match_all('|\{(\w+)\}|', $text, $matches, PREG_SET_ORDER);
121
        foreach ($matches as $match) {
122
            $keyword = $match[1];
123
            $this->keywords[$keyword] = $keyword;
124
        }
125
        preg_match_all('|({assets}/\w+\.\w+)|', $text, $matches, PREG_SET_ORDER);
126
        foreach ($matches as $match) {
127
            $file = $match[1];
128
            $file = str_replace('{assets}', $this->assets_folder, $file);
129
            $this->included_files[$file] = $file;
130
        }
131
132
        return true;
133
    }
134
135
    public function get_keywords(): array
136
    {
137
        return array_keys($this->keywords);
138
    }
139
140
    public function get_assets(): array
141
    {
142
        return array_keys($this->included_files);
143
    }
144
145
    private function create_filelist(): bool
146
    {
147
        $xml = '<xml xmlns:o="urn:schemas-microsoft-com:office:office">' . PHP_EOL;
148
        $xml .= sprintf(' <o:MainFile HRef="../%s"/>', basename($this->template_file)) . PHP_EOL;
149
        $assets = glob($this->assets_folder . "/*");
150
        foreach ($assets as $asset) {
151
            $xml .= sprintf(' <o:File HRef="%s"/>', basename($asset)) . PHP_EOL;
152
        }
153
        $xml .= '</xml>' . PHP_EOL;
154
        $filelist = "$this->assets_folder/filelist.xml";
155
        file_put_contents($filelist, $xml);
156
        $this->included_files[$filelist] = $filelist;
157
158
        return true;
159
    }
160
}
161