Passed
Pull Request — master (#1252)
by
unknown
04:15
created

GlobalConfig::getGlobalPlugins()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 2
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Setting some often needed namespace prefixes
5
 */
6
EasyRdf\RdfNamespace::set('skosmos', 'http://purl.org/net/skosmos#');
7
EasyRdf\RdfNamespace::set('skosext', 'http://purl.org/finnonto/schema/skosext#');
8
EasyRdf\RdfNamespace::delete('geo');
9
EasyRdf\RdfNamespace::set('wgs84', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
10
EasyRdf\RdfNamespace::set('isothes', 'http://purl.org/iso25964/skos-thes#');
11
EasyRdf\RdfNamespace::set('mads', 'http://www.loc.gov/mads/rdf/v1#');
12
EasyRdf\RdfNamespace::set('wd', 'http://www.wikidata.org/entity/');
13
EasyRdf\RdfNamespace::set('wdt', 'http://www.wikidata.org/prop/direct/');
14
15
/**
16
 * GlobalConfig provides access to the Skosmos configuration in config.ttl.
17
 */
18
class GlobalConfig extends BaseConfig {
19
20
    /** Cache reference */
21
    private $cache;
22
    /** Location of the configuration file. Used for caching. */
23
    private $filePath;
24
    /** Namespaces from vocabularies configuration file. */
25
    private $namespaces;
26
    /** EasyRdf\Graph graph */
27
    private $graph;
28
    /**
29
     * @var int the time the config file was last modified
30
     */
31
    private $configModifiedTime = null;
32
33
    const HTTP_URL_PREFIX = 'http://';
34
    const HTTPS_URL_PREFIX = 'https://';
35
36
    public function __construct($config_name='/../config.ttl')
37
    {
38
        // if present, use value from env instead
39
        $config_name_env = getenv('SKOSMOS_CONFIG');
40
        if ($config_name_env) {
41
            $config_name = $config_name_env;
42
        }
43
44
        $this->cache = new Cache();
45
        try {
46
            if (str_starts_with($config_name, self::HTTP_URL_PREFIX) || str_starts_with($config_name, self::HTTPS_URL_PREFIX)) {
47
                $this->filePath = $config_name;
48
            } else {
49
                $this->filePath = realpath( dirname(__FILE__) . $config_name );
50
                if (!file_exists($this->filePath)) {
51
                    throw new Exception($config_name . ' is missing, please provide a config.ttl.');
52
                }
53
            }
54
            $this->initializeConfig();
55
        } catch (Exception $e) {
56
            echo "Error: " . $e->getMessage();
57
            return;
58
        }
59
    }
60
61
    public function getCache()
62
    {
63
        return $this->cache;
64
    }
65
66
    /**
67
     * @return int the time the config file was last modified
68
     */
69
    public function getConfigModifiedTime()
70
    {
71
        return $this->configModifiedTime;
72
    }
73
74
    /**
75
     * Initialize configuration, reading the configuration file from the disk,
76
     * and creating the graph and resources objects. Uses a cache if available,
77
     * in order to avoid re-loading the complete configuration on each request.
78
     */
79
    private function initializeConfig()
80
    {
81
        try {
82
            if (!str_starts_with($this->filePath, self::HTTP_URL_PREFIX) && !str_starts_with($this->filePath, self::HTTPS_URL_PREFIX)) {
83
                // retrieve last modified time for config file (filemtime returns int|bool!)
84
                $configModifiedTime = filemtime($this->filePath);
85
                if (!is_bool($configModifiedTime)) {
0 ignored issues
show
introduced by
The condition is_bool($configModifiedTime) is always false.
Loading history...
86
                    $this->configModifiedTime = $configModifiedTime;
87
                }
88
            }
89
            // use APC user cache to store parsed config.ttl configuration
90
            if ($this->cache->isAvailable() && !is_null($this->configModifiedTime)) {
91
                // @codeCoverageIgnoreStart
92
                $key = realpath($this->filePath) . ", " . $this->configModifiedTime;
93
                $nskey = "namespaces of " . $key;
94
                $this->graph = $this->cache->fetch($key);
95
                $this->namespaces = $this->cache->fetch($nskey);
96
                if ($this->graph === false || $this->namespaces === false) { // was not found in cache
97
                    $this->parseConfig($this->filePath);
98
                    $this->cache->store($key, $this->graph);
99
                    $this->cache->store($nskey, $this->namespaces);
100
                }
101
                // @codeCoverageIgnoreEnd
102
            } else { // APC not available, parse on every request
103
                $this->parseConfig($this->filePath);
104
            }
105
106
            $configResources = $this->graph->allOfType("skosmos:Configuration");
107
            if (is_null($configResources) || !is_array($configResources) || count($configResources) !== 1) {
0 ignored issues
show
introduced by
The condition is_array($configResources) is always true.
Loading history...
108
                throw new Exception("config.ttl must have exactly one skosmos:Configuration");
109
            }
110
111
            $this->resource = $configResources[0];
112
            $this->initializeNamespaces();
113
        } catch (Exception $e) {
114
            echo "Error: " . $e->getMessage();
115
        }      
116
    }
117
118
    /**
119
     * Parses configuration from the config.ttl file
120
     * @param string $filename path to config.ttl file
121
     * @throws \EasyRdf\Exception
122
     */
123
    private function parseConfig($filename)
124
    {
125
        if (str_starts_with($filename, self::HTTP_URL_PREFIX) || str_starts_with($filename, self::HTTPS_URL_PREFIX)) {
126
            $ch = curl_init($filename);
127
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
128
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: text/turtle'));
129
            $contents = curl_exec($ch);
130
            curl_close($ch);
131
        } else {
132
            $contents = file_get_contents($filename);
133
        }
134
        $this->graph = new EasyRdf\Graph();
135
        $parser = new SkosmosTurtleParser();
136
        $parser->parse($this->graph, $contents, 'turtle', $filename);
0 ignored issues
show
Bug introduced by
It seems like $contents can also be of type true; however, parameter $data of EasyRdf\Parser\Turtle::parse() does only seem to accept string, 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

136
        $parser->parse($this->graph, /** @scrutinizer ignore-type */ $contents, 'turtle', $filename);
Loading history...
137
        $this->namespaces = $parser->getNamespaces();
138
    }
139
140
    /**
141
     * Returns the graph created after parsing the configuration file.
142
     * @return \EasyRdf\Graph
143
     */
144
    public function getGraph()
145
    {
146
        return $this->graph;
147
    }
148
149
    /**
150
     * Registers RDF namespaces from the config.ttl file for use by EasyRdf (e.g. serializing)
151
     */
152
    private function initializeNamespaces() {
153
        foreach ($this->namespaces as $prefix => $fullUri) {
154
            if ($prefix != '' && EasyRdf\RdfNamespace::get($prefix) === null) // if not already defined
155
            {
156
                EasyRdf\RdfNamespace::set($prefix, $fullUri);
157
            }
158
        }
159
    }
160
161
    /**
162
     * Returns the UI languages specified in the configuration or defaults to
163
     * only show English
164
     * @return array
165
     */
166
    public function getLanguages()
167
    {
168
        $languageResources = $this->getResource()->getResource('skosmos:languages');
169
        if (!is_null($languageResources) && !empty($languageResources)) {
170
            $languages = array();
171
            foreach ($languageResources as $languageResource) {
172
                /** @var \EasyRdf\Literal $languageName */
173
                $languageName = $languageResource->getLiteral('rdfs:label');
174
                /** @var \EasyRdf\Literal $languageValue */
175
                $languageValue = $languageResource->getLiteral('rdf:value');
176
                if ($languageName && $languageValue) {
177
                    $languages[$languageName->getValue()] = $languageValue->getValue();
178
                }
179
            }
180
            return $languages;
181
        } else {
182
            return array('en' => 'en_GB.utf8');
183
        }
184
    }
185
186
    /**
187
     * Returns the external HTTP request timeout in seconds or the default value
188
     * of 5 seconds if not specified in the configuration.
189
     * @return integer
190
     */
191
    public function getHttpTimeout()
192
    {
193
        return $this->getLiteral('skosmos:httpTimeout', 5);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getLiteral...kosmos:httpTimeout', 5) returns the type string which is incompatible with the documented return type integer.
Loading history...
194
    }
195
196
    /**
197
     * Returns the SPARQL HTTP request timeout in seconds or the default value
198
     * of 20 seconds if not specified in the configuration.
199
     * @return integer
200
     */
201
    public function getSparqlTimeout()
202
    {
203
        return $this->getLiteral('skosmos:sparqlTimeout', 20);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getLiteral...mos:sparqlTimeout', 20) returns the type string which is incompatible with the documented return type integer.
Loading history...
204
    }
205
206
    /**
207
     * Returns the sparql endpoint address defined in the configuration. If
208
     * not then defaulting to http://localhost:3030/ds/sparql
209
     * @return string
210
     */
211
    public function getDefaultEndpoint()
212
    {
213
        $endpoint = $this->resource->get('skosmos:sparqlEndpoint');
214
        if ($endpoint) {
215
            return $endpoint->getUri();
216
        } elseif (getenv('SKOSMOS_SPARQL_ENDPOINT')) {
217
            return getenv('SKOSMOS_SPARQL_ENDPOINT');
218
        } else {
219
            return 'http://localhost:3030/ds/sparql';
220
        }
221
    }
222
223
    /**
224
     * Returns the maximum number of items to return in transitive queries if defined
225
     * in the configuration or the default value of 1000.
226
     * @return integer
227
     */
228
    public function getDefaultTransitiveLimit()
229
    {
230
        return $this->getLiteral('skosmos:transitiveLimit', 1000);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getLiteral...transitiveLimit', 1000) returns the type string which is incompatible with the documented return type integer.
Loading history...
231
    }
232
233
    /**
234
     * Returns the maximum number of items to load at a time if defined
235
     * in the configuration or the default value of 20.
236
     * @return integer
237
     */
238
    public function getSearchResultsSize()
239
    {
240
        return $this->getLiteral('skosmos:searchResultsSize', 20);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getLiteral...searchResultsSize', 20) returns the type string which is incompatible with the documented return type integer.
Loading history...
241
    }
242
243
    /**
244
     * Returns the configured location for the twig template cache and if not
245
     * defined defaults to "/tmp/skosmos-template-cache"
246
     * @return string
247
     */
248
    public function getTemplateCache()
249
    {
250
        return $this->getLiteral('skosmos:templateCache', '/tmp/skosmos-template-cache');
251
    }
252
253
    /**
254
     * Returns the defined sparql-query extension eg. "JenaText" or
255
     * if not defined falling back to SPARQL 1.1
256
     * @return string
257
     */
258
    public function getDefaultSparqlDialect()
259
    {
260
        return $this->getLiteral('skosmos:sparqlDialect', 'Generic');
261
    }
262
263
    /**
264
     * Returns the feedback address defined in the configuration.
265
     * @return string
266
     */
267
    public function getFeedbackAddress()
268
    {
269
        return $this->getLiteral('skosmos:feedbackAddress', null);
270
    }
271
272
    /**
273
     * Returns the feedback sender address defined in the configuration.
274
     * @return string
275
     */
276
    public function getFeedbackSender()
277
    {
278
        return $this->getLiteral('skosmos:feedbackSender', null);
279
    }
280
281
    /**
282
     * Returns the feedback envelope sender address defined in the configuration.
283
     * @return string
284
     */
285
    public function getFeedbackEnvelopeSender()
286
    {
287
        return $this->getLiteral('skosmos:feedbackEnvelopeSender', null);
288
    }
289
290
    /**
291
     * Returns true if exception logging has been configured.
292
     * @return boolean
293
     */
294
    public function getLogCaughtExceptions()
295
    {
296
        return $this->getBoolean('skosmos:logCaughtExceptions', FALSE);
297
    }
298
299
    /**
300
     * Returns true if browser console logging has been enabled,
301
     * @return boolean
302
     */
303
    public function getLoggingBrowserConsole()
304
    {
305
        return $this->getBoolean('skosmos:logBrowserConsole', FALSE);
306
    }
307
308
    /**
309
     * Returns the name of a log file if configured, or NULL otherwise.
310
     * @return string
311
     */
312
    public function getLoggingFilename()
313
    {
314
        return $this->getLiteral('skosmos:logFileName', null);
315
    }
316
317
    /**
318
     * @return string
319
     */
320
    public function getServiceName()
321
    {
322
        return $this->getLiteral('skosmos:serviceName', 'Skosmos');
323
    }
324
325
    /**
326
     * @return string
327
     */
328
    public function getCustomCss()
329
    {
330
        return $this->getLiteral('skosmos:customCss', null);
331
    }
332
333
    /**
334
     * @return boolean
335
     */
336
    public function getUiLanguageDropdown()
337
    {
338
        return $this->getBoolean('skosmos:uiLanguageDropdown', FALSE);
339
    }
340
341
    /**
342
     * @return string
343
     */
344
    public function getBaseHref()
345
    {
346
        return $this->getLiteral('skosmos:baseHref', null);
347
    }
348
349
    /**
350
     * @return array
351
     */
352
    public function getGlobalPlugins()
353
    {
354
        $globalPlugins = array();
355
        $globalPluginsResource =  $this->getResource()->getResource("skosmos:globalPlugins");
356
        if ($globalPluginsResource) {
0 ignored issues
show
introduced by
$globalPluginsResource is of type EasyRdf\Resource, thus it always evaluated to true.
Loading history...
357
            foreach ($globalPluginsResource as $resource) {
358
                $globalPlugins[] = $resource->getValue();
359
            }
360
        }
361
        return $globalPlugins;
362
    }
363
364
    /**
365
     * @return boolean
366
     */
367
    public function getHoneypotEnabled()
368
    {
369
        return $this->getBoolean('skosmos:uiHoneypotEnabled', TRUE);
370
    }
371
372
    /**
373
     * @return integer
374
     */
375
    public function getHoneypotTime()
376
    {
377
        return $this->getLiteral('skosmos:uiHoneypotTime', 5);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getLiteral...mos:uiHoneypotTime', 5) returns the type string which is incompatible with the documented return type integer.
Loading history...
378
    }
379
380
    /**
381
     * @return boolean
382
     */
383
    public function getCollationEnabled()
384
    {
385
        return $this->getBoolean('skosmos:sparqlCollationEnabled', FALSE);
386
    }
387
}
388