1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package midcom |
4
|
|
|
* @author CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
5
|
|
|
* @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/ |
6
|
|
|
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
use midcom\bundle\dependencyInjection\cachePass; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Collection of simple helper methods for testing site configuration |
13
|
|
|
* |
14
|
|
|
* @package midcom |
15
|
|
|
*/ |
16
|
|
|
class midcom_config_test |
17
|
|
|
{ |
18
|
|
|
const OK = 0; |
19
|
|
|
const WARNING = 1; |
20
|
|
|
const ERROR = 2; |
21
|
|
|
|
22
|
|
|
private $messages = [ |
23
|
|
|
'midcom' => [], |
24
|
|
|
'php' => [], |
25
|
|
|
'external' => [] |
26
|
|
|
]; |
27
|
|
|
|
28
|
|
|
private $section; |
29
|
|
|
|
30
|
|
|
private $status = self::OK; |
31
|
|
|
|
32
|
1 |
|
public function check() |
33
|
|
|
{ |
34
|
1 |
|
$this->check_midcom(); |
35
|
1 |
|
$this->check_php(); |
36
|
1 |
|
$this->check_external(); |
37
|
|
|
} |
38
|
|
|
|
39
|
1 |
|
public function get_status() : int |
40
|
|
|
{ |
41
|
1 |
|
return $this->status; |
42
|
|
|
} |
43
|
|
|
|
44
|
1 |
|
private function add(string $testname, int $result_code, string $recommendations = ' ') |
45
|
|
|
{ |
46
|
1 |
|
$this->messages[$this->section][$testname] = [ |
47
|
|
|
'result' => $result_code, |
48
|
|
|
'message' => $recommendations |
49
|
|
|
]; |
50
|
1 |
|
$this->status = max($this->status, $result_code); |
51
|
|
|
} |
52
|
|
|
|
53
|
1 |
|
private function check_midcom() |
54
|
|
|
{ |
55
|
1 |
|
$this->section = 'midcom'; |
56
|
|
|
|
57
|
|
|
// Validate the Cache Base Directory. |
58
|
1 |
|
$cachedir = midcom::get()->getCacheDir(); |
59
|
1 |
|
if (!is_dir($cachedir)) { |
60
|
|
|
$this->add('MidCOM cache base directory', self::ERROR, "The configured MidCOM cache base directory ({$cachedir}) does not exist or is not a directory. You have to create it as a directory writable by the Apache user."); |
61
|
1 |
|
} elseif (!is_writable($cachedir)) { |
62
|
|
|
$this->add('MidCOM cache base directory', self::ERROR, "The configured MidCOM cache base directory ({$cachedir}) is not writable by the Apache user. You have to create it as a directory writable by the Apache user."); |
63
|
|
|
} else { |
64
|
1 |
|
$this->add('MidCOM cache base directory', self::OK, $cachedir); |
65
|
|
|
} |
66
|
|
|
|
67
|
1 |
|
$lang = midcom::get()->i18n->get_current_language(); |
68
|
1 |
|
$locale = Locale::getDefault(); |
69
|
1 |
|
if (!str_starts_with($locale, $lang)) { |
70
|
|
|
$this->add('MidCOM language', self::WARNING, 'Language is set to "' . $lang . '", but the locale "' . $locale . '" is used. This might lead to problems in datamanager number inputs if decimal separators diverge'); |
71
|
|
|
} else { |
72
|
1 |
|
$this->add('MidCOM language', self::OK, $locale); |
73
|
|
|
} |
74
|
|
|
|
75
|
1 |
|
$this->check_rcs(); |
76
|
|
|
} |
77
|
|
|
|
78
|
1 |
|
private function check_rcs() |
79
|
|
|
{ |
80
|
1 |
|
$config = new midcom_services_rcs_config(midcom::get()->config); |
81
|
1 |
|
if ($config->use_rcs()) { |
82
|
|
|
try { |
83
|
1 |
|
$class = $config->get_backend_class(); |
84
|
1 |
|
new $class(new midcom_db_topic, $config); |
85
|
1 |
|
$this->add("MidCOM RCS", self::OK, $class); |
86
|
|
|
} catch (midcom_error $e) { |
87
|
1 |
|
$this->add("MidCOM RCS", self::ERROR, $e->getMessage()); |
88
|
|
|
} |
89
|
|
|
} else { |
90
|
|
|
$this->add("MidCOM RCS", self::WARNING, "The MidCOM RCS service is disabled."); |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
94
|
1 |
|
private function check_php() |
95
|
|
|
{ |
96
|
1 |
|
$this->section = 'php'; |
97
|
|
|
|
98
|
1 |
|
$cur_limit = $this->ini_get_filesize('memory_limit'); |
99
|
1 |
|
if ($cur_limit >= (40 * 1024 * 1024)) { |
100
|
1 |
|
$this->add('Setting: memory_limit', self::OK, ini_get('memory_limit')); |
101
|
|
|
} else { |
102
|
|
|
$this->add('Setting: memory_limit', self::ERROR, "MidCOM requires a minimum memory limit of 40 MB to operate correctly. Smaller amounts will lead to PHP Errors. Detected limit was {$cur_limit}."); |
103
|
|
|
} |
104
|
|
|
|
105
|
1 |
|
$upload_limit = $this->ini_get_filesize('upload_max_filesize'); |
106
|
1 |
|
if ($upload_limit >= (50 * 1024 * 1024)) { |
107
|
|
|
$this->add('Setting: upload_max_filesize', self::OK, ini_get('upload_max_filesize')); |
108
|
|
|
} else { |
109
|
1 |
|
$this->add('Setting: upload_max_filesize', |
110
|
1 |
|
self::WARNING, "To make bulk uploads (for exampe in the Image Gallery) useful, you should increase the Upload limit to something above 50 MB. (Current setting: {$upload_limit})"); |
111
|
|
|
} |
112
|
|
|
|
113
|
1 |
|
$post_limit = $this->ini_get_filesize('post_max_size'); |
114
|
1 |
|
if ($post_limit >= $upload_limit) { |
115
|
1 |
|
$this->add('Setting: post_max_size', self::OK, ini_get('post_max_size')); |
116
|
|
|
} else { |
117
|
|
|
$this->add('Setting: post_max_size', self::WARNING, 'post_max_size should be larger than upload_max_filesize, as both limits apply during uploads.'); |
118
|
|
|
} |
119
|
|
|
|
120
|
1 |
|
$timeout = midcom::get()->config->get('auth_login_session_timeout'); |
121
|
1 |
|
if (ini_get('session.gc_maxlifetime') > $timeout) { |
122
|
|
|
$this->add('Setting: session.gc_maxlifetime', self::OK, ini_get('session.gc_maxlifetime')); |
123
|
|
|
} else { |
124
|
1 |
|
$this->add('Setting: session.gc_maxlifetime', self::WARNING, 'session.gc_maxlifetime should be greater than auth_login_session_timeout (' . $timeout . '), otherwise login sessions will time out earlier than intended.'); |
125
|
|
|
} |
126
|
|
|
|
127
|
1 |
|
if (ini_get("opcache.enable") == "1") { |
128
|
1 |
|
$this->add("OPCache", self::OK); |
129
|
|
|
} else { |
130
|
|
|
$this->add("OPCache", self::WARNING, "OPCache is recommended for efficient MidCOM operation"); |
131
|
|
|
} |
132
|
|
|
|
133
|
1 |
|
$this->check_memcached(); |
134
|
|
|
|
135
|
1 |
|
if (!function_exists('exif_read_data')) { |
136
|
|
|
$this->add('EXIF reader', self::WARNING, 'PHP-EXIF is not available. It required for proper operation of Image Gallery components.'); |
137
|
|
|
} else { |
138
|
1 |
|
$this->add('EXIF reader', self::OK); |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
|
142
|
1 |
|
private function check_memcached() |
143
|
|
|
{ |
144
|
1 |
|
if (midcom::get()->config->get('cache_module_memcache_backend') !== 'memcached') { |
145
|
|
|
$this->add('Memcache', self::WARNING, 'Configured backend: ' . midcom::get()->config->get('cache_module_memcache_backend')); |
146
|
1 |
|
} elseif (!class_exists('Memcached')) { |
147
|
|
|
$this->add('Memcache', self::WARNING, 'The PHP memcached module is recommended for efficient MidCOM operation.'); |
148
|
|
|
} else { |
149
|
1 |
|
$config = midcom::get()->config->get_array('cache_module_memcache_backend_config'); |
150
|
1 |
|
$memcached = cachePass::prepare_memcached($config); |
151
|
|
|
// Sometimes, addServer returns true even if the server is not running, so we call a command to make sure it's actually working |
152
|
1 |
|
if ($memcached && $memcached->getVersion()) { |
153
|
1 |
|
$this->add('Memcache', self::OK); |
154
|
|
|
} else { |
155
|
|
|
$this->add('Memcache', self::ERROR, "The PHP memcached module is available and set to be in use, but it cannot be connected to."); |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
} |
159
|
|
|
|
160
|
1 |
|
private function ini_get_filesize(string $setting) : int |
161
|
|
|
{ |
162
|
1 |
|
$result = ini_get($setting); |
163
|
1 |
|
$last_char = $result[-1]; |
164
|
1 |
|
if ($last_char == 'M') { |
165
|
1 |
|
$result = substr($result, 0, -1) * 1024 * 1024; |
166
|
|
|
} elseif ($last_char == 'K') { |
167
|
|
|
$result = substr($result, 0, -1) * 1024; |
168
|
|
|
} elseif ($last_char == 'G') { |
169
|
|
|
$result = substr($result, 0, -1) * 1024 * 1024 * 1024; |
170
|
|
|
} |
171
|
1 |
|
return $result; |
172
|
|
|
} |
173
|
|
|
|
174
|
1 |
|
private function check_external() |
175
|
|
|
{ |
176
|
1 |
|
$this->section = 'external'; |
177
|
|
|
// ImageMagick |
178
|
1 |
|
$cmd = midcom::get()->config->get('utility_imagemagick_base') . "identify -version"; |
179
|
1 |
|
exec($cmd, $output, $result); |
180
|
1 |
|
if (!in_array($result, [0, 1], true)) { |
181
|
|
|
$this->add('ImageMagick', self::ERROR, 'The existence ImageMagick toolkit could not be verified, it is required for all kinds of image processing in MidCOM.'); |
182
|
|
|
} else { |
183
|
1 |
|
$this->add('ImageMagick', self::OK, implode("<br>", $output)); |
184
|
|
|
} |
185
|
|
|
|
186
|
1 |
|
$this->check_for_utility('jpegtran', self::WARNING, 'The jpegtran utility is used for lossless JPEG operations, even though ImageMagick can do the same conversions, the lossless features provided by this utility are used where appropriate, so its installation is recommended unless it is known to cause problems.', 'The jpegtran utility is used for lossless rotations of JPEG images. If there are problems with image rotations, disabling jpegtran, which will cause ImageMagick to be used instead, probably helps.'); |
187
|
|
|
|
188
|
1 |
|
if (midcom::get()->config->get('indexer_backend')) { |
189
|
|
|
$this->check_for_utility('catdoc', self::ERROR, 'Catdoc is required to properly index Microsoft Word documents. It is strongly recommended to install it, otherwise Word documents will be indexed as binary files.'); |
190
|
|
|
$this->check_for_utility('pdftotext', self::ERROR, 'pdftotext is required to properly index Adobe PDF documents. It is strongly recommended to install it, otherwise PDF documents will be indexed as binary files.'); |
191
|
|
|
$this->check_for_utility('unrtf', self::ERROR, 'unrtf is required to properly index Rich Text Format documents. It is strongly recommended to install it, otherwise RTF documents will be indexed as binary files.'); |
192
|
|
|
} |
193
|
|
|
} |
194
|
|
|
|
195
|
1 |
|
private function check_for_utility(string $testname, int $fail_code, string $fail_recommendations, string $recommendations = '') |
196
|
|
|
{ |
197
|
1 |
|
$executable = midcom::get()->config->get("utility_{$testname}"); |
198
|
1 |
|
if ($executable === null) { |
199
|
|
|
$this->add($testname, $fail_code, "The path to the utility {$testname} is not configured. {$fail_recommendations}"); |
200
|
1 |
|
} elseif (!exec('which which')) { |
201
|
|
|
$this->add('which', self::ERROR, "The 'which' utility cannot be found."); |
202
|
|
|
} else { |
203
|
1 |
|
exec("which {$executable}", $output, $exitcode); |
204
|
1 |
|
if ($exitcode == 0) { |
205
|
|
|
$this->add($testname, self::OK, $recommendations); |
206
|
|
|
} else { |
207
|
1 |
|
$this->add($testname, $fail_code, "The utility {$testname} is not correctly configured: File ({$executable}) not found. {$fail_recommendations}"); |
208
|
|
|
} |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
public function show() |
213
|
|
|
{ |
214
|
|
|
echo '<table>'; |
215
|
|
|
|
216
|
|
|
$this->print_section('MidCOM ' . midcom::VERSION, $this->messages['midcom']); |
217
|
|
|
$this->print_section($_SERVER['SERVER_SOFTWARE'], $this->messages['php']); |
218
|
|
|
$this->print_section('External Utilities', $this->messages['external']); |
219
|
|
|
|
220
|
|
|
echo '</table>'; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
private function print_section(string $heading, array $messages) |
224
|
|
|
{ |
225
|
|
|
echo " <tr>\n"; |
226
|
|
|
echo " <th colspan=\"2\">{$heading}</th>\n"; |
227
|
|
|
echo " </tr>\n"; |
228
|
|
|
|
229
|
|
|
foreach ($messages as $testname => $data) { |
230
|
|
|
echo " <tr class=\"test\">\n <th>\n"; |
231
|
|
|
switch ($data['result']) { |
232
|
|
|
case self::OK: |
233
|
|
|
echo " <i class='fa fa-check' style='color: green;' title='OK'></i>"; |
234
|
|
|
break; |
235
|
|
|
|
236
|
|
|
case self::WARNING: |
237
|
|
|
echo " <i class='fa fa-exclamation-triangle' style='color: orange;' title='WARNING'></i>"; |
238
|
|
|
break; |
239
|
|
|
|
240
|
|
|
case self::ERROR: |
241
|
|
|
echo " <i class='fa fa-exclamation-circle' style='color: red;' title='ERROR'></i>"; |
242
|
|
|
break; |
243
|
|
|
|
244
|
|
|
default: |
245
|
|
|
throw new midcom_error("Unknown error code {$data['result']}."); |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
echo " {$testname}</th>\n"; |
249
|
|
|
echo " <td>{$data['message']}</td>\n"; |
250
|
|
|
echo " </tr>\n"; |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
} |
254
|
|
|
|