Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( 8387e4...c20ef5 )
by Sebastian
03:31 queued 10s
created

Indexer::delete()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 64
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 49
c 4
b 0
f 0
dl 0
loc 64
rs 8.1793
cc 7
nc 13
nop 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A Indexer::getIndexFieldName() 0 16 5

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * (c) Kitodo. Key to digital objects e.V. <[email protected]>
5
 *
6
 * This file is part of the Kitodo and TYPO3 projects.
7
 *
8
 * @license GNU General Public License version 3 or later.
9
 * For the full copyright and license information, please read the
10
 * LICENSE.txt file that was distributed with this source code.
11
 */
12
13
namespace Kitodo\Dlf\Common;
14
15
use TYPO3\CMS\Core\Database\ConnectionPool;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use Ubl\Iiif\Tools\IiifHelper;
18
use Ubl\Iiif\Presentation\Common\Model\Resources\AnnotationContainerInterface;
19
20
/**
21
 * Indexer class for the 'dlf' extension
22
 *
23
 * @author Sebastian Meyer <[email protected]>
24
 * @package TYPO3
25
 * @subpackage dlf
26
 * @access public
27
 */
28
class Indexer
29
{
30
    /**
31
     * The extension key
32
     *
33
     * @var string
34
     * @access public
35
     */
36
    public static $extKey = 'dlf';
37
38
    /**
39
     * Array of metadata fields' configuration
40
     * @see loadIndexConf()
41
     *
42
     * @var array
43
     * @access protected
44
     */
45
    protected static $fields = [
46
        'autocomplete' => [],
47
        'facets' => [],
48
        'sortables' => [],
49
        'indexed' => [],
50
        'stored' => [],
51
        'tokenized' => [],
52
        'fieldboost' => []
53
    ];
54
55
    /**
56
     * Is the index configuration loaded?
57
     * @see $fields
58
     *
59
     * @var bool
60
     * @access protected
61
     */
62
    protected static $fieldsLoaded = false;
63
64
    /**
65
     * List of already processed documents
66
     *
67
     * @var array
68
     * @access protected
69
     */
70
    protected static $processedDocs = [];
71
72
    /**
73
     * Instance of \Kitodo\Dlf\Common\Solr class
74
     *
75
     * @var \Kitodo\Dlf\Common\Solr
76
     * @access protected
77
     */
78
    protected static $solr;
79
80
    /**
81
     * Insert given document into Solr index
82
     *
83
     * @access public
84
     *
85
     * @param \Kitodo\Dlf\Common\Document &$doc: The document to add
86
     * @param int $core: UID of the Solr core to use
87
     *
88
     * @return int 0 on success or 1 on failure
89
     */
90
    public static function add(Document &$doc, $core = 0)
91
    {
92
        if (in_array($doc->uid, self::$processedDocs)) {
93
            return 0;
94
        } elseif (self::solrConnect($core, $doc->pid)) {
95
            $errors = 0;
96
            // Handle multi-volume documents.
97
            if ($doc->parentId) {
98
                $parent = Document::getInstance($doc->parentId, 0, true);
99
                if ($parent->ready) {
100
                    $errors = self::add($parent, $core);
101
                } else {
102
                    Helper::devLog('Could not load parent document with UID ' . $doc->parentId, DEVLOG_SEVERITY_ERROR);
103
                    return 1;
104
                }
105
            }
106
            try {
107
                // Add document to list of processed documents.
108
                self::$processedDocs[] = $doc->uid;
109
                // Delete old Solr documents.
110
                $updateQuery = self::$solr->service->createUpdate();
111
                $updateQuery->addDeleteQuery('uid:' . $doc->uid);
112
                self::$solr->service->update($updateQuery);
113
                // Index every logical unit as separate Solr document.
114
                foreach ($doc->tableOfContents as $logicalUnit) {
115
                    if (!$errors) {
116
                        $errors = self::processLogical($doc, $logicalUnit);
117
                    } else {
118
                        break;
119
                    }
120
                }
121
                // Index fulltext files if available.
122
                if ($doc->hasFulltext) {
123
                    foreach ($doc->physicalStructure as $pageNumber => $xmlId) {
124
                        if (!$errors) {
125
                            $errors = self::processPhysical($doc, $pageNumber, $doc->physicalStructureInfo[$xmlId]);
126
                        } else {
127
                            break;
128
                        }
129
                    }
130
                }
131
                // Commit all changes.
132
                $updateQuery = self::$solr->service->createUpdate();
133
                $updateQuery->addCommit();
134
                self::$solr->service->update($updateQuery);
135
136
                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
137
                    ->getQueryBuilderForTable('tx_dlf_documents');
138
139
                // Get document title from database.
140
                $result = $queryBuilder
141
                    ->select('tx_dlf_documents.title AS title')
142
                    ->from('tx_dlf_documents')
143
                    ->where(
144
                        $queryBuilder->expr()->eq('tx_dlf_documents.uid', intval($doc->uid)),
145
                        Helper::whereExpression('tx_dlf_documents')
146
                    )
147
                    ->setMaxResults(1)
148
                    ->execute();
149
150
                $allResults = $result->fetchAll();
151
                $resArray = $allResults[0];
152
                if (!(\TYPO3_REQUESTTYPE & \TYPO3_REQUESTTYPE_CLI)) {
153
                    if (!$errors) {
154
                        Helper::addMessage(
155
                            htmlspecialchars(sprintf(Helper::getMessage('flash.documentIndexed'), $resArray['title'], $doc->uid)),
156
                            Helper::getMessage('flash.done', true),
157
                            \TYPO3\CMS\Core\Messaging\FlashMessage::OK,
158
                            true,
159
                            'core.template.flashMessages'
160
                        );
161
                    } else {
162
                        Helper::addMessage(
163
                            htmlspecialchars(sprintf(Helper::getMessage('flash.documentNotIndexed'), $resArray['title'], $doc->uid)),
164
                            Helper::getMessage('flash.error', true),
165
                            \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
166
                            true,
167
                            'core.template.flashMessages'
168
                        );
169
                    }
170
                }
171
                return $errors;
172
            } catch (\Exception $e) {
173
                if (!(\TYPO3_REQUESTTYPE & \TYPO3_REQUESTTYPE_CLI)) {
174
                    Helper::addMessage(
175
                        Helper::getMessage('flash.solrException', true) . '<br />' . htmlspecialchars($e->getMessage()),
176
                        Helper::getMessage('flash.error', true),
177
                        \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
178
                        true,
179
                        'core.template.flashMessages'
180
                    );
181
                }
182
                Helper::devLog('Apache Solr threw exception: "' . $e->getMessage() . '"', DEVLOG_SEVERITY_ERROR);
183
                return 1;
184
            }
185
        } else {
186
            if (!(\TYPO3_REQUESTTYPE & \TYPO3_REQUESTTYPE_CLI)) {
187
                Helper::addMessage(
188
                    Helper::getMessage('flash.solrNoConnection', true),
189
                    Helper::getMessage('flash.warning', true),
190
                    \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING,
191
                    true,
192
                    'core.template.flashMessages'
193
                );
194
            }
195
            Helper::devLog('Could not connect to Apache Solr server', DEVLOG_SEVERITY_ERROR);
196
            return 1;
197
        }
198
    }
199
200
    /**
201
     * Returns the dynamic index field name for the given metadata field.
202
     *
203
     * @access public
204
     *
205
     * @param string $index_name: The metadata field's name in database
206
     * @param int $pid: UID of the configuration page
207
     *
208
     * @return string The field's dynamic index name
209
     */
210
    public static function getIndexFieldName($index_name, $pid = 0)
211
    {
212
        // Sanitize input.
213
        $pid = max(intval($pid), 0);
214
        if (!$pid) {
215
            Helper::devLog('Invalid PID ' . $pid . ' for metadata configuration', DEVLOG_SEVERITY_ERROR);
216
            return '';
217
        }
218
        // Load metadata configuration.
219
        self::loadIndexConf($pid);
220
        // Build field's suffix.
221
        $suffix = (in_array($index_name, self::$fields['tokenized']) ? 't' : 'u');
222
        $suffix .= (in_array($index_name, self::$fields['stored']) ? 's' : 'u');
223
        $suffix .= (in_array($index_name, self::$fields['indexed']) ? 'i' : 'u');
224
        $index_name .= '_' . $suffix;
225
        return $index_name;
226
    }
227
228
    /**
229
     * Load indexing configuration
230
     *
231
     * @access protected
232
     *
233
     * @param int $pid: The configuration page's UID
234
     *
235
     * @return void
236
     */
237
    protected static function loadIndexConf($pid)
238
    {
239
        if (!self::$fieldsLoaded) {
240
            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
241
                ->getQueryBuilderForTable('tx_dlf_metadata');
242
243
            // Get the metadata indexing options.
244
            $result = $queryBuilder
245
                ->select(
246
                    'tx_dlf_metadata.index_name AS index_name',
247
                    'tx_dlf_metadata.index_tokenized AS index_tokenized',
248
                    'tx_dlf_metadata.index_stored AS index_stored',
249
                    'tx_dlf_metadata.index_indexed AS index_indexed',
250
                    'tx_dlf_metadata.is_sortable AS is_sortable',
251
                    'tx_dlf_metadata.is_facet AS is_facet',
252
                    'tx_dlf_metadata.is_listed AS is_listed',
253
                    'tx_dlf_metadata.index_autocomplete AS index_autocomplete',
254
                    'tx_dlf_metadata.index_boost AS index_boost'
255
                )
256
                ->from('tx_dlf_metadata')
257
                ->where(
258
                    $queryBuilder->expr()->eq('tx_dlf_metadata.pid', intval($pid)),
259
                    Helper::whereExpression('tx_dlf_metadata')
260
                )
261
                ->execute();
262
263
            while ($indexing = $result->fetch()) {
264
                if ($indexing['index_tokenized']) {
265
                    self::$fields['tokenized'][] = $indexing['index_name'];
266
                }
267
                if (
268
                    $indexing['index_stored']
269
                    || $indexing['is_listed']
270
                ) {
271
                    self::$fields['stored'][] = $indexing['index_name'];
272
                }
273
                if (
274
                    $indexing['index_indexed']
275
                    || $indexing['index_autocomplete']
276
                ) {
277
                    self::$fields['indexed'][] = $indexing['index_name'];
278
                }
279
                if ($indexing['is_sortable']) {
280
                    self::$fields['sortables'][] = $indexing['index_name'];
281
                }
282
                if ($indexing['is_facet']) {
283
                    self::$fields['facets'][] = $indexing['index_name'];
284
                }
285
                if ($indexing['index_autocomplete']) {
286
                    self::$fields['autocomplete'][] = $indexing['index_name'];
287
                }
288
                if ($indexing['index_boost'] > 0.0) {
289
                    self::$fields['fieldboost'][$indexing['index_name']] = floatval($indexing['index_boost']);
290
                } else {
291
                    self::$fields['fieldboost'][$indexing['index_name']] = false;
292
                }
293
            }
294
            self::$fieldsLoaded = true;
295
        }
296
    }
297
298
    /**
299
     * Processes a logical unit (and its children) for the Solr index
300
     *
301
     * @access protected
302
     *
303
     * @param \Kitodo\Dlf\Common\Document &$doc: The METS document
304
     * @param array $logicalUnit: Array of the logical unit to process
305
     *
306
     * @return int 0 on success or 1 on failure
307
     */
308
    protected static function processLogical(Document &$doc, array $logicalUnit)
309
    {
310
        $errors = 0;
311
        // Get metadata for logical unit.
312
        $metadata = $doc->metadataArray[$logicalUnit['id']];
313
        if (!empty($metadata)) {
314
            // Remove appended "valueURI" from authors' names for indexing.
315
            if (is_array($metadata['author'])) {
316
                foreach ($metadata['author'] as $i => $author) {
317
                    $splitName = explode(chr(31), $author);
318
                    $metadata['author'][$i] = $splitName[0];
319
                }
320
            }
321
            // Create new Solr document.
322
            $updateQuery = self::$solr->service->createUpdate();
323
            $solrDoc = $updateQuery->createDocument();
324
            // Create unique identifier from document's UID and unit's XML ID.
325
            $solrDoc->setField('id', $doc->uid . $logicalUnit['id']);
326
            $solrDoc->setField('uid', $doc->uid);
327
            $solrDoc->setField('pid', $doc->pid);
328
            if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($logicalUnit['points'])) {
329
                $solrDoc->setField('page', $logicalUnit['points']);
330
            }
331
            if ($logicalUnit['id'] == $doc->toplevelId) {
332
                $solrDoc->setField('thumbnail', $doc->thumbnail);
333
            } elseif (!empty($logicalUnit['thumbnailId'])) {
334
                $solrDoc->setField('thumbnail', $doc->getFileLocation($logicalUnit['thumbnailId']));
335
            }
336
            $solrDoc->setField('partof', $doc->parentId);
337
            $solrDoc->setField('root', $doc->rootId);
338
            $solrDoc->setField('sid', $logicalUnit['id']);
339
            // There can be only one toplevel unit per UID, independently of backend configuration
340
            $solrDoc->setField('toplevel', $logicalUnit['id'] == $doc->toplevelId ? true : false);
341
            $solrDoc->setField('type', $logicalUnit['type'], self::$fields['fieldboost']['type']);
342
            $solrDoc->setField('title', $metadata['title'][0], self::$fields['fieldboost']['title']);
343
            $solrDoc->setField('volume', $metadata['volume'][0], self::$fields['fieldboost']['volume']);
344
            $solrDoc->setField('record_id', $metadata['record_id'][0]);
345
            $solrDoc->setField('purl', $metadata['purl'][0]);
346
            $solrDoc->setField('location', $doc->location);
347
            $solrDoc->setField('urn', $metadata['urn']);
348
            $solrDoc->setField('license', $metadata['license']);
349
            $solrDoc->setField('terms', $metadata['terms']);
350
            $solrDoc->setField('restrictions', $metadata['restrictions']);
351
            $solrDoc->setField('collection', $doc->metadataArray[$doc->toplevelId]['collection']);
352
            $coordinates = json_decode($metadata['coordinates'][0]);
353
            if (is_object($coordinates)) {
354
                $solrDoc->setField('geom', json_encode($coordinates->features[0]));
355
            }
356
            $autocomplete = [];
357
            foreach ($metadata as $index_name => $data) {
358
                if (
359
                    !empty($data)
360
                    && substr($index_name, -8) !== '_sorting'
361
                ) {
362
                    $solrDoc->setField(self::getIndexFieldName($index_name, $doc->pid), $data, self::$fields['fieldboost'][$index_name]);
363
                    if (in_array($index_name, self::$fields['sortables'])) {
364
                        // Add sortable fields to index.
365
                        $solrDoc->setField($index_name . '_sorting', $metadata[$index_name . '_sorting'][0]);
366
                    }
367
                    if (in_array($index_name, self::$fields['facets'])) {
368
                        // Add facets to index.
369
                        $solrDoc->setField($index_name . '_faceting', $data);
370
                    }
371
                    if (in_array($index_name, self::$fields['autocomplete'])) {
372
                        $autocomplete = array_merge($autocomplete, $data);
373
                    }
374
                }
375
            }
376
            // Add autocomplete values to index.
377
            if (!empty($autocomplete)) {
378
                $solrDoc->setField('autocomplete', $autocomplete);
379
            }
380
            // Add collection information to logical sub-elements if applicable.
381
            if (
382
                in_array('collection', self::$fields['facets'])
383
                && empty($metadata['collection'])
384
                && !empty($doc->metadataArray[$doc->toplevelId]['collection'])
385
            ) {
386
                $solrDoc->setField('collection_faceting', $doc->metadataArray[$doc->toplevelId]['collection']);
387
            }
388
            try {
389
                $updateQuery->addDocument($solrDoc);
390
                self::$solr->service->update($updateQuery);
391
            } catch (\Exception $e) {
392
                if (!(\TYPO3_REQUESTTYPE & \TYPO3_REQUESTTYPE_CLI)) {
393
                    Helper::addMessage(
394
                        Helper::getMessage('flash.solrException', true) . '<br />' . htmlspecialchars($e->getMessage()),
395
                        Helper::getMessage('flash.error', true),
396
                        \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
397
                        true,
398
                        'core.template.flashMessages'
399
                    );
400
                }
401
                return 1;
402
            }
403
        }
404
        // Check for child elements...
405
        if (!empty($logicalUnit['children'])) {
406
            foreach ($logicalUnit['children'] as $child) {
407
                if (!$errors) {
408
                    // ...and process them, too.
409
                    $errors = self::processLogical($doc, $child);
410
                } else {
411
                    break;
412
                }
413
            }
414
        }
415
        return $errors;
416
    }
417
418
    /**
419
     * Processes a physical unit for the Solr index
420
     *
421
     * @access protected
422
     *
423
     * @param \Kitodo\Dlf\Common\Document &$doc: The METS document
424
     * @param int $page: The page number
425
     * @param array $physicalUnit: Array of the physical unit to process
426
     *
427
     * @return int 0 on success or 1 on failure
428
     */
429
    protected static function processPhysical(Document &$doc, $page, array $physicalUnit)
430
    {
431
        $errors = 0;
432
        // Read extension configuration.
433
        $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][self::$extKey]);
434
        if (
435
            !empty($physicalUnit['files'][$extConf['fileGrpFulltext']])
436
            || !empty($annotationContainerIds = $physicalUnit['annotationContainers'])
437
        ) {
438
            if (!empty($physicalUnit['files'][$extConf['fileGrpFulltext']])) {
439
                $file = $doc->getFileLocation($physicalUnit['files'][$extConf['fileGrpFulltext']]);
440
                // Load XML file.
441
                if (GeneralUtility::isValidUrl($file)) {
442
                    // Set user-agent to identify self when fetching XML data.
443
                    if (!empty($extConf['useragent'])) {
444
                        @ini_set('user_agent', $extConf['useragent']);
445
                    }
446
                    $fileResource = GeneralUtility::getUrl($file);
447
                    if ($fileResource !== false) {
448
                        // Turn off libxml's error logging.
449
                        $libxmlErrors = libxml_use_internal_errors(true);
450
                        // disable entity loading
451
                        $previousValueOfEntityLoader = libxml_disable_entity_loader(true);
452
                        // Load XML from file.
453
                        $xml = simplexml_load_string($fileResource);
454
                        // reset entity loader setting
455
                        libxml_disable_entity_loader($previousValueOfEntityLoader);
456
                        // Reset libxml's error logging.
457
                        libxml_use_internal_errors($libxmlErrors);
458
                        if ($xml === false) {
459
                            return 1;
460
                        }
461
                    } else {
462
                        return 1;
463
                    }
464
                } else {
465
                    return 1;
466
                }
467
            }
468
            if (isset($annotationContainerIds) && !empty($annotationContainerIds)) {
469
                foreach ($annotationContainerIds as $annotationContainerId) {
470
                    if (!empty($extConf['useragent'])) {
471
                        @ini_set('user_agent', $extConf['useragent']);
472
                    }
473
                    $fileResource = GeneralUtility::getUrl($annotationContainerId);
474
                    if ($fileResource !== false) {
475
                        $annotationContainer = IiifHelper::loadIiifResource($fileResource);
476
                        if (!($annotationContainer instanceof AnnotationContainerInterface)) {
477
                            return 1;
478
                        }
479
                    } else {
480
                        return 1;
481
                    }
482
                }
483
            }
484
            // Create new Solr document.
485
            $updateQuery = self::$solr->service->createUpdate();
486
            $solrDoc = $updateQuery->createDocument();
487
            // Create unique identifier from document's UID and unit's XML ID.
488
            $solrDoc->setField('id', $doc->uid . $physicalUnit['id']);
489
            $solrDoc->setField('uid', $doc->uid);
490
            $solrDoc->setField('pid', $doc->pid);
491
            $solrDoc->setField('page', $page);
492
            if (!empty($physicalUnit['files'][$extConf['fileGrpThumbs']])) {
493
                $solrDoc->setField('thumbnail', $doc->getFileLocation($physicalUnit['files'][$extConf['fileGrpThumbs']]));
494
            }
495
            $solrDoc->setField('partof', $doc->parentId);
496
            $solrDoc->setField('root', $doc->rootId);
497
            $solrDoc->setField('sid', $physicalUnit['id']);
498
            $solrDoc->setField('toplevel', false);
499
            $solrDoc->setField('type', $physicalUnit['type'], self::$fields['fieldboost']['type']);
500
            $solrDoc->setField('collection', $doc->metadataArray[$doc->toplevelId]['collection']);
501
            $solrDoc->setField('fulltext', htmlspecialchars($doc->getRawText($physicalUnit['id'])));
502
            // Add faceting information to physical sub-elements if applicable.
503
            foreach ($doc->metadataArray[$doc->toplevelId] as $index_name => $data) {
504
                if (
505
                    !empty($data)
506
                    && substr($index_name, -8) !== '_sorting'
507
                ) {
508
509
                    if (in_array($index_name, self::$fields['facets'])) {
510
                        // Remove appended "valueURI" from authors' names for indexing.
511
                        if ($index_name == 'author') {
512
                            foreach ($data as $i => $author) {
513
                                $splitName = explode(chr(31), $author);
514
                                $data[$i] = $splitName[0];
515
                            }
516
                        }
517
                        // Add facets to index.
518
                        $solrDoc->setField($index_name . '_faceting', $data);
519
                    }
520
                }
521
            }
522
            // Add collection information to physical sub-elements if applicable.
523
            if (
524
                in_array('collection', self::$fields['facets'])
525
                && !empty($doc->metadataArray[$doc->toplevelId]['collection'])
526
            ) {
527
                $solrDoc->setField('collection_faceting', $doc->metadataArray[$doc->toplevelId]['collection']);
528
            }
529
            try {
530
                $updateQuery->addDocument($solrDoc);
531
                self::$solr->service->update($updateQuery);
532
            } catch (\Exception $e) {
533
                if (!(\TYPO3_REQUESTTYPE & \TYPO3_REQUESTTYPE_CLI)) {
534
                    Helper::addMessage(
535
                        Helper::getMessage('flash.solrException', true) . '<br />' . htmlspecialchars($e->getMessage()),
536
                        Helper::getMessage('flash.error', true),
537
                        \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR,
538
                        true,
539
                        'core.template.flashMessages'
540
                    );
541
                }
542
                return 1;
543
            }
544
        }
545
        return $errors;
546
    }
547
548
    /**
549
     * Connects to Solr server.
550
     *
551
     * @access protected
552
     *
553
     * @param int $core: UID of the Solr core
554
     * @param int $pid: UID of the configuration page
555
     *
556
     * @return bool true on success or false on failure
557
     */
558
    protected static function solrConnect($core, $pid = 0)
559
    {
560
        // Get Solr instance.
561
        if (!self::$solr) {
562
            // Connect to Solr server.
563
            if (self::$solr = Solr::getInstance($core)) {
564
                // Load indexing configuration if needed.
565
                if ($pid) {
566
                    self::loadIndexConf($pid);
567
                }
568
            } else {
569
                return false;
570
            }
571
        }
572
        return true;
573
    }
574
575
    /**
576
     * Prevent instantiation by hiding the constructor
577
     *
578
     * @access private
579
     */
580
    private function __construct()
581
    {
582
        // This is a static class, thus no instances should be created.
583
    }
584
}
585