XML_Response   F
last analyzed

Complexity

Total Complexity 102

Size/Duplication

Total Lines 662
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 102
eloc 357
dl 0
loc 662
rs 2
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
A writeRssMusicInfo() 0 31 5
A writeZedAttr() 0 6 1
C writeRssCdata() 0 63 14
A writeRssConsoleInfo() 0 11 1
A buildCdata() 0 18 4
F setTvAttr() 0 32 19
A writeRssMovieInfo() 0 11 1
A __construct() 0 20 1
A includeMetaInfo() 0 24 3
A returnReg() 0 11 1
A returnCaps() 0 13 1
A includeImage() 0 11 1
A includeRssAtomLink() 0 13 2
A returnApiRssXml() 0 16 1
A returnApiXml() 0 15 1
A addNode() 0 7 2
B includeReleaseMain() 0 32 7
A includeRssAtom() 0 12 1
A includeTotalRows() 0 6 1
A writeCategoryListing() 0 20 5
A includeLimits() 0 14 3
A includeReleases() 0 16 4
A returnXML() 0 24 6
A addNodes() 0 9 2
C setZedAttributes() 0 40 15

How to fix   Complexity   

Complex Class

Complex classes like XML_Response often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use XML_Response, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program (see LICENSE.txt in the base directory.  If
16
 * not, see:
17
 *
18
 * @link      <http://www.gnu.org/licenses/>.
19
 *
20
 * @author    ruhllatio
21
 * @copyright 2016 nZEDb
22
 */
23
24
namespace App\Http\Controllers\Api;
25
26
use App\Models\Category;
27
use App\Models\Release;
28
use Illuminate\Support\Carbon;
29
30
/**
31
 * Class XMLReturn.
32
 */
33
class XML_Response
34
{
35
    /**
36
     * @var string The buffered cData before final write
37
     */
38
    protected string $cdata;
39
40
    /**
41
     * The RSS namespace used for the output.
42
     */
43
    protected string $namespace;
44
45
    /**
46
     * The trailing URL parameters on the request.
47
     */
48
    protected mixed $parameters;
49
50
    /**
51
     * The release we are adding to the stream.
52
     */
53
    protected mixed $release;
54
55
    /**
56
     * The retrieved releases we are returning from the API call.
57
     */
58
    protected mixed $releases;
59
60
    /**
61
     * The various server variables and active categories.
62
     */
63
    protected mixed $server;
64
65
    /**
66
     * The XML formatting operation we are returning.
67
     */
68
    protected mixed $type;
69
70
    /**
71
     * The XMLWriter Class.
72
     */
73
    protected \XMLWriter $xml;
74
75
    protected mixed $offset;
76
77
    /**
78
     * XMLReturn constructor.
79
     */
80
    public function __construct(array $options = [])
81
    {
82
        $defaults = [
83
            'Parameters' => null,
84
            'Data' => null,
85
            'Server' => null,
86
            'Offset' => null,
87
            'Type' => null,
88
        ];
89
        $options += $defaults;
90
91
        $this->parameters = $options['Parameters'];
92
        $this->releases = $options['Data'];
93
        $this->server = $options['Server'];
94
        $this->offset = $options['Offset'];
95
        $this->type = $options['Type'];
96
97
        $this->xml = new \XMLWriter;
98
        $this->xml->openMemory();
99
        $this->xml->setIndent(true);
100
    }
101
102
    public function returnXML(): bool|string
103
    {
104
        if ($this->xml) {
105
            switch ($this->type) {
106
                case 'caps':
107
                    return $this->returnCaps();
108
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
109
                case 'api':
110
                    $this->namespace = 'newznab';
111
112
                    return $this->returnApiXml();
113
                    break;
114
                case 'rss':
115
                    $this->namespace = 'nntmux';
116
117
                    return $this->returnApiRssXml();
118
                    break;
119
                case 'reg':
120
                    return $this->returnReg();
121
                    break;
122
            }
123
        }
124
125
        return false;
126
    }
127
128
    /**
129
     * XML writes and returns the API capabilities.
130
     *
131
     * @return string The XML Formatted string data
132
     */
133
    protected function returnCaps(): string
134
    {
135
        $this->xml->startDocument('1.0', 'UTF-8');
136
        $this->xml->startElement('caps');
137
        $this->addNode(['name' => 'server', 'data' => $this->server['server']]);
138
        $this->addNode(['name' => 'limits', 'data' => $this->server['limits']]);
139
        $this->addNode(['name' => 'registration', 'data' => $this->server['registration']]);
140
        $this->addNodes(['name' => 'searching', 'data' => $this->server['searching']]);
141
        $this->writeCategoryListing();
142
        $this->xml->endElement();
143
        $this->xml->endDocument();
144
145
        return $this->xml->outputMemory();
146
    }
147
148
    /**
149
     * XML writes and returns the API data.
150
     *
151
     * @return string The XML Formatted string data
152
     */
153
    protected function returnApiRssXml(): string
154
    {
155
        $this->xml->startDocument('1.0', 'UTF-8');
156
        $this->includeRssAtom(); // Open RSS
157
        $this->xml->startElement('channel'); // Open channel
158
        $this->includeRssAtomLink();
159
        $this->includeMetaInfo();
160
        $this->includeImage();
161
        $this->includeTotalRows();
162
        $this->includeLimits();
163
        $this->includeReleases();
164
        $this->xml->endElement(); // End channel
165
        $this->xml->endElement(); // End RSS
166
        $this->xml->endDocument();
167
168
        return $this->xml->outputMemory();
169
    }
170
171
    /**
172
     * XML writes and returns the API data.
173
     *
174
     * @return string The XML Formatted string data
175
     */
176
    protected function returnApiXml(): string
177
    {
178
        $this->xml->startDocument('1.0', 'UTF-8');
179
        $this->includeRssAtom(); // Open RSS
180
        $this->xml->startElement('channel'); // Open channel
181
        $this->includeMetaInfo();
182
        $this->includeImage();
183
        $this->includeTotalRows();
184
        $this->includeLimits();
185
        $this->includeReleases();
186
        $this->xml->endElement(); // End channel
187
        $this->xml->endElement(); // End RSS
188
        $this->xml->endDocument();
189
190
        return $this->xml->outputMemory();
191
    }
192
193
    /**
194
     * @return string The XML formatted registration information
195
     */
196
    protected function returnReg(): string
197
    {
198
        $this->xml->startDocument('1.0', 'UTF-8');
199
        $this->xml->startElement('register');
200
        $this->xml->writeAttribute('username', $this->parameters['username']);
201
        $this->xml->writeAttribute('password', $this->parameters['password']);
202
        $this->xml->writeAttribute('apikey', $this->parameters['token']);
203
        $this->xml->endElement();
204
        $this->xml->endDocument();
205
206
        return $this->xml->outputMemory();
207
    }
208
209
    /**
210
     * Starts a new element, loops through the attribute data and ends the element.
211
     *
212
     * @param  array  $element  An array with the name of the element and the attribute data
213
     */
214
    protected function addNode(array $element): void
215
    {
216
        $this->xml->startElement($element['name']);
217
        foreach ($element['data'] as $attr => $val) {
218
            $this->xml->writeAttribute($attr, $val);
219
        }
220
        $this->xml->endElement();
221
    }
222
223
    /**
224
     * Starts a new element, loops through the attribute data and ends the element.
225
     *
226
     * @param  array  $element  An array with the name of the element and the attribute data
227
     */
228
    protected function addNodes(array $element): void
229
    {
230
        $this->xml->startElement($element['name']);
231
        foreach ($element['data'] as $elem => $value) {
232
            $subelement['name'] = $elem;
233
            $subelement['data'] = $value;
234
            $this->addNode($subelement);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $subelement seems to be defined later in this foreach loop on line 232. Are you sure it is defined here?
Loading history...
235
        }
236
        $this->xml->endElement();
237
    }
238
239
    /**
240
     * Adds the site category listing to the XML feed.
241
     */
242
    protected function writeCategoryListing(): void
243
    {
244
        $this->xml->startElement('categories');
245
        foreach ($this->server['categories'] as $this->parameters) {
246
            $this->xml->startElement('category');
247
            $this->xml->writeAttribute('id', $this->parameters['id']);
248
            $this->xml->writeAttribute('name', html_entity_decode($this->parameters['title']));
249
            if (! empty($this->parameters['description'])) {
250
                $this->xml->writeAttribute('description', html_entity_decode($this->parameters['description']));
251
            }
252
            foreach ($this->parameters['categories'] as $c) {
253
                $this->xml->startElement('subcat');
254
                $this->xml->writeAttribute('id', $c['id']);
255
                $this->xml->writeAttribute('name', html_entity_decode($c['title']));
256
                if (! empty($c['description'])) {
257
                    $this->xml->writeAttribute('description', html_entity_decode($c['description']));
258
                }
259
                $this->xml->endElement();
260
            }
261
            $this->xml->endElement();
262
        }
263
    }
264
265
    /**
266
     * Adds RSS Atom information to the XML.
267
     */
268
    protected function includeRssAtom(): void
269
    {
270
        $url = match ($this->namespace) {
271
            'newznab' => 'http://www.newznab.com/DTD/2010/feeds/attributes/',
272
            default => $this->server['server']['url'].'/rss-info/',
273
        };
274
275
        $this->xml->startElement('rss');
276
        $this->xml->writeAttribute('version', '2.0');
277
        $this->xml->writeAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
278
        $this->xml->writeAttribute("xmlns:{$this->namespace}", $url);
279
        $this->xml->writeAttribute('encoding', 'utf-8');
280
    }
281
282
    protected function includeRssAtomLink(): void
283
    {
284
        $this->xml->startElement('atom:link');
285
        $this->xml->startAttribute('href');
286
        $this->xml->text($this->server['server']['url'].($this->namespace === 'newznab' ? '/api/v1/api' : '/rss'));
287
        $this->xml->endAttribute();
288
        $this->xml->startAttribute('rel');
289
        $this->xml->text('self');
290
        $this->xml->endAttribute();
291
        $this->xml->startAttribute('type');
292
        $this->xml->text('application/rss+xml');
293
        $this->xml->endAttribute();
294
        $this->xml->endElement();
295
    }
296
297
    /**
298
     * Writes the channel information for the feed.
299
     */
300
    protected function includeMetaInfo(): void
301
    {
302
        $server = $this->server['server'];
303
304
        switch ($this->namespace) {
305
            case 'newznab':
306
                $path = '/apihelp/';
307
                $tag = 'API';
308
                break;
309
            case 'nntmux':
310
            default:
311
                $path = '/rss-info/';
312
                $tag = 'RSS';
313
        }
314
315
        $this->xml->writeElement('title', $server['title']);
316
        $this->xml->writeElement('description', $server['title']." {$tag} Details");
317
        $this->xml->writeElement('link', $server['url']);
318
        $this->xml->writeElement('language', 'en-gb');
319
        $this->xml->writeElement('webMaster', $server['email'].' '.$server['title']);
320
        $this->xml->writeElement('category', $server['meta']);
321
        $this->xml->writeElement('generator', 'nntmux');
322
        $this->xml->writeElement('ttl', '10');
323
        $this->xml->writeElement('docs', $this->server['server']['url'].$path);
324
    }
325
326
    /**
327
     * Adds nntmux logo data to the XML.
328
     */
329
    protected function includeImage(): void
330
    {
331
        $this->xml->startElement('image');
332
        $this->xml->writeAttribute('url', $this->server['server']['url'].'/assets/images/tmux_logo.png');
333
        $this->xml->writeAttribute('title', $this->server['server']['title']);
334
        $this->xml->writeAttribute('link', $this->server['server']['url']);
335
        $this->xml->writeAttribute(
336
            'description',
337
            'Visit '.$this->server['server']['title'].' - '.$this->server['server']['strapline']
338
        );
339
        $this->xml->endElement();
340
    }
341
342
    public function includeTotalRows(): void
343
    {
344
        $this->xml->startElement($this->namespace.':response');
345
        $this->xml->writeAttribute('offset', $this->offset);
346
        $this->xml->writeAttribute('total', $this->releases[0]->_totalrows ?? 0);
347
        $this->xml->endElement();
348
    }
349
350
    public function includeLimits(): void
351
    {
352
        $this->xml->startElement($this->namespace.':apilimits');
353
        $this->xml->writeAttribute('apicurrent', $this->parameters['requests']);
354
        $this->xml->writeAttribute('apimax', $this->parameters['apilimit']);
355
        $this->xml->writeAttribute('grabcurrent', $this->parameters['grabs']);
356
        $this->xml->writeAttribute('grabmax', $this->parameters['downloadlimit']);
357
        if (! empty($this->parameters['oldestapi'])) {
358
            $this->xml->writeAttribute('apioldesttime', $this->parameters['oldestapi']);
359
        }
360
        if (! empty($this->parameters['oldestgrab'])) {
361
            $this->xml->writeAttribute('graboldesttime', $this->parameters['oldestgrab']);
362
        }
363
        $this->xml->endElement();
364
    }
365
366
    /**
367
     * Loop through the releases and add their info to the XML stream.
368
     */
369
    public function includeReleases(): void
370
    {
371
        if (! empty($this->releases)) {
372
            if (! $this->releases instanceof Release) {
373
                foreach ($this->releases as $this->release) {
374
                    $this->xml->startElement('item');
375
                    $this->includeReleaseMain();
376
                    $this->setZedAttributes();
377
                    $this->xml->endElement();
378
                }
379
            } else {
380
                $this->release = $this->releases;
381
                $this->xml->startElement('item');
382
                $this->includeReleaseMain();
383
                $this->setZedAttributes();
384
                $this->xml->endElement();
385
            }
386
        }
387
    }
388
389
    /**
390
     * Writes the primary release information.
391
     */
392
    public function includeReleaseMain(): void
393
    {
394
        $this->xml->writeElement('title', $this->release->searchname);
395
        $this->xml->startElement('guid');
396
        $this->xml->writeAttribute('isPermaLink', 'true');
397
        $this->xml->text("{$this->server['server']['url']}/details/{$this->release->guid}");
398
        $this->xml->endElement();
399
        $this->xml->writeElement(
400
            'link',
401
            "{$this->server['server']['url']}/getnzb?id={$this->release->guid}.nzb".
402
            "&r={$this->parameters['token']}".
403
            ((int) $this->parameters['del'] === 1 ? '&del=1' : '')
404
        );
405
        $this->xml->writeElement('comments', "{$this->server['server']['url']}/details/{$this->release->guid}#comments");
406
        $this->xml->writeElement('pubDate', date(DATE_RSS, strtotime($this->release->adddate)));
407
        $this->xml->writeElement('category', $this->release->category_name);
408
        if ($this->namespace === 'newznab') {
409
            $this->xml->writeElement('description', $this->release->searchname);
410
        } else {
411
            $this->writeRssCdata();
412
        }
413
        if (! isset($this->parameters['dl']) || (isset($this->parameters['dl']) && (int) $this->parameters['dl'] === 1)) {
414
            $this->xml->startElement('enclosure');
415
            $this->xml->writeAttribute(
416
                'url',
417
                "{$this->server['server']['url']}/getnzb?id={$this->release->guid}.nzb".
418
                "&r={$this->parameters['token']}".
419
                ((int) $this->parameters['del'] === 1 ? '&del=1' : '')
420
            );
421
            $this->xml->writeAttribute('length', $this->release->size);
422
            $this->xml->writeAttribute('type', 'application/x-nzb');
423
            $this->xml->endElement();
424
        }
425
    }
426
427
    /**
428
     * Writes the Zed (newznab) specific attributes.
429
     */
430
    protected function setZedAttributes(): void
431
    {
432
        $this->writeZedAttr('category', $this->release->categories_id);
433
        $this->writeZedAttr('size', $this->release->size);
434
        if (! empty($this->release->coverurl)) {
435
            $this->writeZedAttr(
436
                'coverurl',
437
                $this->server['server']['url']."/covers/{$this->release->coverurl}"
438
            );
439
        }
440
441
        if ((int) $this->parameters['extended'] === 1) {
442
            $this->writeZedAttr('files', $this->release->totalpart);
443
            if (($this->release->videos_id > 0 || $this->release->tv_episodes_id > 0) && $this->namespace === 'newznab') {
444
                $this->setTvAttr();
445
            }
446
447
            if (isset($this->release->imdbid) && $this->release->imdbid > 0) {
448
                $this->writeZedAttr('imdb', $this->release->imdbid);
449
            }
450
            if (isset($this->release->anidbid) && $this->release->anidbid > 0) {
451
                $this->writeZedAttr('anidbid', $this->release->anidbid);
452
            }
453
            if (isset($this->release->predb_id) && $this->release->predb_id > 0) {
454
                $this->writeZedAttr('prematch', 1);
455
            }
456
            if (isset($this->release->nfostatus) && (int) $this->release->nfostatus === 1) {
457
                $this->writeZedAttr(
458
                    'info',
459
                    $this->server['server']['url'].
460
                    "api?t=info&id={$this->release->guid}&r={$this->parameters['token']}"
461
                );
462
            }
463
464
            $this->writeZedAttr('grabs', $this->release->grabs);
465
            $this->writeZedAttr('comments', $this->release->comments);
466
            $this->writeZedAttr('password', $this->release->passwordstatus);
467
            $this->writeZedAttr('usenetdate', Carbon::parse($this->release->postdate)->toRssString());
468
            if (! empty($this->release->group_name)) {
469
                $this->writeZedAttr('group', $this->release->group_name);
470
            }
471
        }
472
    }
473
474
    /**
475
     * Writes the TV Specific attributes.
476
     */
477
    protected function setTvAttr(): void
478
    {
479
        if (! empty($this->release->title)) {
480
            $this->writeZedAttr('title', $this->release->title);
481
        }
482
        if (isset($this->release->series) && $this->release->series > 0) {
483
            $this->writeZedAttr('season', $this->release->series);
484
        }
485
        if (isset($this->release->episode->episode) && $this->release->episode->episode > 0) {
486
            $this->writeZedAttr('episode', $this->release->episode->episode);
487
        }
488
        if (! empty($this->release->firstaired)) {
489
            $this->writeZedAttr('tvairdate', $this->release->firstaired);
490
        }
491
        if (isset($this->release->tvdb) && $this->release->tvdb > 0) {
492
            $this->writeZedAttr('tvdbid', $this->release->tvdb);
493
        }
494
        if (isset($this->release->trakt) && $this->release->trakt > 0) {
495
            $this->writeZedAttr('traktid', $this->release->trakt);
496
        }
497
        if (isset($this->release->tvrage) && $this->release->tvrage > 0) {
498
            $this->writeZedAttr('tvrageid', $this->release->tvrage);
499
            $this->writeZedAttr('rageid', $this->release->tvrage);
500
        }
501
        if (isset($this->release->tvmaze) && $this->release->tvmaze > 0) {
502
            $this->writeZedAttr('tvmazeid', $this->release->tvmaze);
503
        }
504
        if (isset($this->release->imdb) && $this->release->imdb > 0) {
505
            $this->writeZedAttr('imdbid', $this->release->imdb);
506
        }
507
        if (isset($this->release->tmdb) && $this->release->tmdb > 0) {
508
            $this->writeZedAttr('tmdbid', $this->release->tmdb);
509
        }
510
    }
511
512
    /**
513
     * Writes individual zed (newznab) type attributes.
514
     *
515
     * @param  string  $name  The namespaced attribute name tag
516
     * @param  string|null  $value  The namespaced attribute value
517
     */
518
    protected function writeZedAttr(string $name, ?string $value): void
519
    {
520
        $this->xml->startElement($this->namespace.':attr');
521
        $this->xml->writeAttribute('name', $name);
522
        $this->xml->writeAttribute('value', $value);
523
        $this->xml->endElement();
524
    }
525
526
    /**
527
     * Writes the cData (HTML format) for the RSS feed
528
     * Also calls supplementary cData writes depending upon post process.
529
     */
530
    protected function writeRssCdata(): void
531
    {
532
        $this->cdata = "\n\t<div>\n";
533
        switch (1) {
534
            case ! empty($this->release->cover):
535
                $dir = 'movies';
536
                $column = 'imdbid';
537
                break;
538
            case ! empty($this->release->mu_cover):
539
                $dir = 'music';
540
                $column = 'musicinfo_id';
541
                break;
542
            case ! empty($this->release->co_cover):
543
                $dir = 'console';
544
                $column = 'consoleinfo_id';
545
                break;
546
            case ! empty($this->release->bo_cover):
547
                $dir = 'books';
548
                $column = 'bookinfo_id';
549
                break;
550
        }
551
        if (isset($dir, $column)) {
552
            $dcov = ($dir === 'movies' ? '-cover' : '');
553
            $this->cdata .=
554
                "\t<img style=\"margin-left:10px;margin-bottom:10px;float:right;\" ".
555
                "src=\"{$this->server['server']['url']}/covers/{$dir}/{$this->release->$column}{$dcov}.jpg\" ".
556
                "width=\"120\" alt=\"{$this->release->searchname}\" />\n";
557
        }
558
        $size = human_filesize($this->release->size);
559
        $this->cdata .=
560
            "\t<li>ID: <a href=\"{$this->server['server']['url']}/details/{$this->release->guid}\">{$this->release->guid}</a></li>\n".
561
            "\t<li>Name: {$this->release->searchname}</li>\n".
562
            "\t<li>Size: {$size}</li>\n".
563
            "\t<li>Category: <a href=\"{$this->server['server']['url']}/browse/{$this->release->category_name}\">{$this->release->category_name}</a></li>\n".
564
            "\t<li>Group: <a href=\"{$this->server['server']['url']}/browse/group?g={$this->release->group_name}\">{$this->release->group_name}</a></li>\n".
565
            "\t<li>Poster: {$this->release->fromname}</li>\n".
566
            "\t<li>Posted: {$this->release->postdate}</li>\n";
567
568
        $pstatus = match ($this->release->passwordstatus) {
569
            0 => 'None',
570
            1 => 'Possibly Passworded',
571
            2 => 'Probably not viable',
572
            10 => 'Passworded',
573
            default => 'Unknown',
574
        };
575
        $this->cdata .= "\t<li>Password: {$pstatus}</li>\n";
576
        if ($this->release->nfostatus === 1) {
577
            $this->cdata .=
578
                "\t<li>Nfo: ".
579
                "<a href=\"{$this->server['server']['url']}/api?t=nfo&id={$this->release->guid}&raw=1&i={$this->parameters['uid']}&r={$this->parameters['token']}\">".
580
                "{$this->release->searchname}.nfo</a></li>\n";
581
        }
582
583
        if ($this->release->parentid === Category::MOVIE_ROOT && $this->release->imdbid !== '') {
584
            $this->writeRssMovieInfo();
585
        } elseif ($this->release->parentid === Category::MUSIC_ROOT && $this->release->musicinfo_id > 0) {
586
            $this->writeRssMusicInfo();
587
        } elseif ($this->release->parentid === Category::GAME_ROOT && $this->release->consoleinfo_id > 0) {
588
            $this->writeRssConsoleInfo();
589
        }
590
        $this->xml->startElement('description');
591
        $this->xml->writeCdata($this->cdata."\t</div>");
592
        $this->xml->endElement();
593
    }
594
595
    /**
596
     * Writes the Movie Info for the RSS feed cData.
597
     */
598
    protected function writeRssMovieInfo(): void
599
    {
600
        $movieCol = ['rating', 'plot', 'year', 'genre', 'director', 'actors'];
601
602
        $cData = $this->buildCdata($movieCol);
603
604
        $this->cdata .=
605
            "\t<li>Imdb Info:
606
				\t<ul>
607
					\t<li>IMDB Link: <a href=\"http://www.imdb.com/title/tt{$this->release->imdbid}/\">{$this->release->searchname}</a></li>\n
608
					\t{$cData}
609
				\t</ul>
610
			\t</li>
611
			\n";
612
    }
613
614
    /**
615
     * Writes the Music Info for the RSS feed cData.
616
     */
617
    protected function writeRssMusicInfo(): void
618
    {
619
        $tData = $cDataUrl = '';
620
621
        $musicCol = ['mu_artist', 'mu_genre', 'mu_publisher', 'mu_releasedate', 'mu_review'];
622
623
        $cData = $this->buildCdata($musicCol);
624
625
        if ($this->release->mu_url !== '') {
626
            $cDataUrl = "<li>Amazon: <a href=\"{$this->release->mu_url}\">{$this->release->mu_title}</a></li>";
627
        }
628
629
        $this->cdata .=
630
            "\t<li>Music Info:
631
			<ul>
632
			{$cDataUrl}
633
			{$cData}
634
			</ul>
635
			</li>\n";
636
        if ($this->release->mu_tracks !== '') {
637
            $tracks = explode('|', $this->release->mu_tracks);
638
            if (\count($tracks) > 0) {
639
                foreach ($tracks as $track) {
640
                    $track = trim($track);
641
                    $tData .= "<li>{$track}</li>";
642
                }
643
            }
644
            $this->cdata .= "
645
			<li>Track Listing:
646
				<ol>
647
				{$tData}
648
				</ol>
649
			</li>\n";
650
        }
651
    }
652
653
    /**
654
     * Writes the Console Info for the RSS feed cData.
655
     */
656
    protected function writeRssConsoleInfo(): void
657
    {
658
        $gamesCol = ['co_genre', 'co_publisher', 'year', 'co_review'];
659
660
        $cData = $this->buildCdata($gamesCol);
661
662
        $this->cdata .= "
663
		<li>Console Info:
664
			<ul>
665
				<li>Amazon: <a href=\"{$this->release->co_url}\">{$this->release->co_title}</a></li>\n
666
				{$cData}
667
			</ul>
668
		</li>\n";
669
    }
670
671
    /**
672
     * Accepts an array of values to loop through to build cData from the release info.
673
     *
674
     * @param  array  $columns  The columns in the release we need to insert
675
     * @return string The HTML format cData
676
     */
677
    protected function buildCdata(array $columns): string
678
    {
679
        $cData = '';
680
681
        foreach ($columns as $info) {
682
            if (! empty($this->release->$info)) {
683
                if ($info === 'mu_releasedate') {
684
                    $ucInfo = 'Released';
685
                    $rDate = date('Y-m-d', strtotime($this->release->$info));
686
                    $cData .= "<li>{$ucInfo}: {$rDate}</li>\n";
687
                } else {
688
                    $ucInfo = ucfirst(preg_replace('/^[a-z]{2}_/i', '', $info));
689
                    $cData .= "<li>{$ucInfo}: {$this->release->$info}</li>\n";
690
                }
691
            }
692
        }
693
694
        return $cData;
695
    }
696
}
697