Completed
Push — dev ( dc1167...d83514 )
by Darko
07:36
created

XML_Response::includeReleaseMain()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 32
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
eloc 27
c 0
b 0
f 0
dl 0
loc 32
ccs 0
cts 21
cp 0
rs 8.5546
cc 7
nc 4
nop 0
crap 56
1
<?php
2
/**
3
 * This program is free software: you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation, either version 3 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program (see LICENSE.txt in the base directory.  If
15
 * not, see:
16
 *
17
 * @link      <http://www.gnu.org/licenses/>.
18
 * @author    ruhllatio
19
 * @copyright 2016 nZEDb
20
 */
21
22
namespace Blacklight\http;
23
24
use App\Models\Release;
25
use App\Models\Category;
26
use Illuminate\Support\Carbon;
27
28
/**
29
 * Class XMLReturn.
30
 */
31
class XML_Response
32
{
33
    /**
34
     * @var string The buffered cData before final write
35
     */
36
    protected $cdata;
37
38
    /**
39
     * The RSS namespace used for the output.
40
     *
41
     * @var string
42
     */
43
    protected $namespace;
44
45
    /**
46
     * The trailing URL parameters on the request.
47
     *
48
     * @var mixed
49
     */
50
    protected $parameters;
51
52
    /**
53
     * The release we are adding to the stream.
54
     *
55
     * @var mixed
56
     */
57
    protected $release;
58
59
    /**
60
     * The retrieved releases we are returning from the API call.
61
     *
62
     * @var mixed
63
     */
64
    protected $releases;
65
66
    /**
67
     * The various server variables and active categories.
68
     *
69
     * @var mixed
70
     */
71
    protected $server;
72
73
    /**
74
     * The XML formatting operation we are returning.
75
     *
76
     * @var mixed
77
     */
78
    protected $type;
79
80
    /**
81
     * The XMLWriter Class.
82
     *
83
     * @var \XMLWriter
84
     */
85
    protected $xml;
86
87
    /**
88
     * @var mixed
89
     */
90
    protected $offset;
91
92
    /**
93
     * XMLReturn constructor.
94
     *
95
     * @param array $options
96
     */
97
    public function __construct(array $options = [])
98
    {
99
        $defaults = [
100
            'Parameters' => null,
101
            'Data'       => null,
102
            'Server'     => null,
103
            'Offset'     => null,
104
            'Type'       => null,
105
        ];
106
        $options += $defaults;
107
108
        $this->parameters = $options['Parameters'];
109
        $this->releases = $options['Data'];
110
        $this->server = $options['Server'];
111
        $this->offset = $options['Offset'];
112
        $this->type = $options['Type'];
113
114
        $this->xml = new \XMLWriter();
115
        $this->xml->openMemory();
116
        $this->xml->setIndent(true);
117
    }
118
119
    /**
120
     * @return bool|string
121
     */
122
    public function returnXML()
123
    {
124
        if ($this->xml) {
125
            switch ($this->type) {
126
                case 'caps':
127
                    return $this->returnCaps();
128
                    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...
129
                case 'api':
130
                    $this->namespace = 'newznab';
131
132
                    return $this->returnApiRss();
133
                    break;
134
                case 'rss':
135
                    $this->namespace = 'nntmux';
136
137
                    return $this->returnApiRss();
138
                    break;
139
                case 'reg':
140
                    return $this->returnReg();
141
                    break;
142
            }
143
        }
144
145
        return false;
146
    }
147
148
    /**
149
     * XML writes and returns the API capabilities.
150
     *
151
     * @return string The XML Formatted string data
152
     */
153
    protected function returnCaps(): string
154
    {
155
        $this->xml->startDocument('1.0', 'UTF-8');
156
        $this->xml->startElement('caps');
157
        $this->addNode(['name' => 'server', 'data' => $this->server['server']]);
158
        $this->addNode(['name' => 'limits', 'data' => $this->server['limits']]);
159
        $this->addNode(['name' => 'registration', 'data' => $this->server['registration']]);
160
        $this->addNodes(['name' => 'searching', 'data' => $this->server['searching']]);
161
        $this->writeCategoryListing();
162
        $this->xml->endElement();
163
        $this->xml->endDocument();
164
165
        return $this->xml->outputMemory();
166
    }
167
168
    /**
169
     * XML writes and returns the API data.
170
     *
171
     * @return string The XML Formatted string data
172
     */
173
    protected function returnApiRss(): string
174
    {
175
        $this->xml->startDocument('1.0', 'UTF-8');
176
        $this->includeRssAtom(); // Open RSS
177
        $this->xml->startElement('channel'); // Open channel
178
        $this->includeRssAtomLink();
179
        $this->includeMetaInfo();
180
        $this->includeImage();
181
        $this->includeTotalRows();
182
        $this->includeLimits();
183
        $this->includeReleases();
184
        $this->xml->endElement(); // End channel
185
        $this->xml->endElement(); // End RSS
186
        $this->xml->endDocument();
187
188
        return $this->xml->outputMemory();
189
    }
190
191
    /**
192
     * @return string The XML formatted registration information
193
     */
194
    protected function returnReg(): string
195
    {
196
        $this->xml->startDocument('1.0', 'UTF-8');
197
        $this->xml->startElement('register');
198
        $this->xml->writeAttribute('username', $this->parameters['username']);
199
        $this->xml->writeAttribute('password', $this->parameters['password']);
200
        $this->xml->writeAttribute('apikey', $this->parameters['token']);
201
        $this->xml->endElement();
202
        $this->xml->endDocument();
203
204
        return $this->xml->outputMemory();
205
    }
206
207
    /**
208
     * Starts a new element, loops through the attribute data and ends the element.
209
     *
210
     * @param array $element An array with the name of the element and the attribute data
211
     */
212
    protected function addNode($element): void
213
    {
214
        $this->xml->startElement($element['name']);
215
        foreach ($element['data'] as $attr => $val) {
216
            $this->xml->writeAttribute($attr, $val);
217
        }
218
        $this->xml->endElement();
219
    }
220
221
    /**
222
     * Starts a new element, loops through the attribute data and ends the element.
223
     *
224
     * @param array $element An array with the name of the element and the attribute data
225
     */
226
    protected function addNodes($element): void
227
    {
228
        $this->xml->startElement($element['name']);
229
        foreach ($element['data'] as $elem => $value) {
230
            $subelement['name'] = $elem;
231
            $subelement['data'] = $value;
232
            $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 230. Are you sure it is defined here?
Loading history...
233
        }
234
        $this->xml->endElement();
235
    }
236
237
    /**
238
     * Adds the site category listing to the XML feed.
239
     */
240
    protected function writeCategoryListing(): void
241
    {
242
        $this->xml->startElement('categories');
243
        foreach ($this->server['categories'] as $this->parameters) {
244
            $this->xml->startElement('category');
245
            $this->xml->writeAttribute('id', $this->parameters['id']);
246
            $this->xml->writeAttribute('name', html_entity_decode($this->parameters['title']));
247
            if (! empty($this->parameters['description'])) {
248
                $this->xml->writeAttribute('description', html_entity_decode($this->parameters['description']));
249
            }
250
            foreach ($this->parameters['categories'] as $c) {
251
                $this->xml->startElement('subcat');
252
                $this->xml->writeAttribute('id', $c['id']);
253
                $this->xml->writeAttribute('name', html_entity_decode($c['title']));
254
                if (! empty($c['description'])) {
255
                    $this->xml->writeAttribute('description', html_entity_decode($c['description']));
256
                }
257
                $this->xml->endElement();
258
            }
259
            $this->xml->endElement();
260
        }
261
    }
262
263
    /**
264
     * Adds RSS Atom information to the XML.
265
     */
266
    protected function includeRssAtom(): void
267
    {
268
        switch ($this->namespace) {
269
            case 'newznab':
270
                $url = 'http://www.newznab.com/DTD/2010/feeds/attributes/';
271
                break;
272
            case 'nntmux':
273
            default:
274
                $url = $this->server['server']['url'].'/rss-info/';
275
        }
276
277
        $this->xml->startElement('rss');
278
        $this->xml->writeAttribute('version', '2.0');
279
        $this->xml->writeAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
280
        $this->xml->writeAttribute("xmlns:{$this->namespace}", $url);
281
        $this->xml->writeAttribute('encoding', 'utf-8');
282
    }
283
284
    protected function includeRssAtomLink(): void
285
    {
286
        $this->xml->startElement('atom:link');
287
        $this->xml->startAttribute('href');
288
        $this->xml->text($this->server['server']['url'].($this->namespace === 'newznab' ? '/api/v1/api' : '/rss'));
289
        $this->xml->endAttribute();
290
        $this->xml->startAttribute('rel');
291
        $this->xml->text('self');
292
        $this->xml->endAttribute();
293
        $this->xml->startAttribute('type');
294
        $this->xml->text('application/rss+xml');
295
        $this->xml->endAttribute();
296
        $this->xml->endElement();
297
    }
298
299
    /**
300
     * Writes the channel information for the feed.
301
     */
302
    protected function includeMetaInfo(): void
303
    {
304
        $server = $this->server['server'];
305
306
        switch ($this->namespace) {
307
            case 'newznab':
308
                $path = '/apihelp/';
309
                $tag = 'API';
310
                break;
311
            case 'nntmux':
312
            default:
313
                $path = '/rss-info/';
314
                $tag = 'RSS';
315
        }
316
317
        $this->xml->writeElement('title', $server['title']);
318
        $this->xml->writeElement('description', $server['title']." {$tag} Details");
319
        $this->xml->writeElement('link', $server['url']);
320
        $this->xml->writeElement('language', 'en-gb');
321
        $this->xml->writeElement('webMaster', $server['email'].' '.$server['title']);
322
        $this->xml->writeElement('category', $server['meta']);
323
        $this->xml->writeElement('generator', 'nntmux');
324
        $this->xml->writeElement('ttl', '10');
325
        $this->xml->writeElement('docs', $this->server['server']['url'].$path);
326
    }
327
328
    /**
329
     * Adds nntmux logo data to the XML.
330
     */
331
    protected function includeImage(): void
332
    {
333
        $this->xml->startElement('image');
334
        $this->xml->writeAttribute('url', $this->server['server']['url'].'/assets/images/tmux_logo.png');
335
        $this->xml->writeAttribute('title', $this->server['server']['title']);
336
        $this->xml->writeAttribute('link', $this->server['server']['url']);
337
        $this->xml->writeAttribute(
338
            'description',
339
            'Visit '.$this->server['server']['title'].' - '.$this->server['server']['strapline']
340
        );
341
        $this->xml->endElement();
342
    }
343
344
    public function includeTotalRows(): void
345
    {
346
        $this->xml->startElement($this->namespace.':response');
347
        $this->xml->writeAttribute('offset', $this->offset);
348
        $this->xml->writeAttribute('total', $this->releases[0]->_totalrows ?? 0);
349
        $this->xml->endElement();
350
    }
351
352
    public function includeLimits(): void
353
    {
354
        $this->xml->startElement($this->namespace.':apilimits');
355
        $this->xml->writeAttribute('apiCurrent', $this->parameters['requests']);
356
        $this->xml->writeAttribute('apiMax', $this->parameters['apilimit']);
357
        $this->xml->writeAttribute('grabCurrent', $this->parameters['grabs']);
358
        $this->xml->writeAttribute('grabMax', $this->parameters['downloadlimit']);
359
        $this->xml->endElement();
360
    }
361
362
    /**
363
     * Loop through the releases and add their info to the XML stream.
364
     */
365
    public function includeReleases(): void
366
    {
367
        if (! empty($this->releases)) {
368
            if (! $this->releases instanceof Release) {
369
                foreach ($this->releases as $this->release) {
370
                    $this->xml->startElement('item');
371
                    $this->includeReleaseMain();
372
                    $this->setZedAttributes();
373
                    $this->xml->endElement();
374
                }
375
            } elseif ($this->releases instanceof Release) {
0 ignored issues
show
introduced by
$this->releases is always a sub-type of App\Models\Release.
Loading history...
376
                $this->release = $this->releases;
377
                $this->xml->startElement('item');
378
                $this->includeReleaseMain();
379
                $this->setZedAttributes();
380
                $this->xml->endElement();
381
            }
382
        }
383
    }
384
385
    /**
386
     * Writes the primary release information.
387
     */
388
    public function includeReleaseMain(): void
389
    {
390
        $this->xml->writeElement('title', $this->release->searchname);
391
        $this->xml->startElement('guid');
392
        $this->xml->writeAttribute('isPermaLink', 'true');
393
        $this->xml->text("{$this->server['server']['url']}/details/{$this->release->guid}");
394
        $this->xml->endElement();
395
        $this->xml->writeElement(
396
            'link',
397
            "{$this->server['server']['url']}/getnzb?id={$this->release->guid}.nzb".
398
            "&r={$this->parameters['token']}".
399
            ((int) $this->parameters['del'] === 1 ? '&del=1' : '')
400
        );
401
        $this->xml->writeElement('comments', "{$this->server['server']['url']}/details/{$this->release->guid}#comments");
402
        $this->xml->writeElement('pubDate', date(DATE_RSS, strtotime($this->release->adddate)));
403
        $this->xml->writeElement('category', $this->release->category_name);
404
        if ($this->namespace === 'newznab') {
405
            $this->xml->writeElement('description', $this->release->searchname);
406
        } else {
407
            $this->writeRssCdata();
408
        }
409
        if (! isset($this->parameters['dl']) || (isset($this->parameters['dl']) && (int) $this->parameters['dl'] === 1)) {
410
            $this->xml->startElement('enclosure');
411
            $this->xml->writeAttribute(
412
                'url',
413
                "{$this->server['server']['url']}/getnzb?id={$this->release->guid}.nzb".
414
                "&r={$this->parameters['token']}".
415
                ((int) $this->parameters['del'] === 1 ? '&del=1' : '')
416
            );
417
            $this->xml->writeAttribute('length', $this->release->size);
418
            $this->xml->writeAttribute('type', 'application/x-nzb');
419
            $this->xml->endElement();
420
        }
421
    }
422
423
    /**
424
     * Writes the Zed (newznab) specific attributes.
425
     */
426
    protected function setZedAttributes(): void
427
    {
428
        $this->writeZedAttr('category', $this->release->categories_id);
429
        $this->writeZedAttr('size', $this->release->size);
430
        if (isset($this->release->coverurl) && ! empty($this->release->coverurl)) {
431
            $this->writeZedAttr(
432
                'coverurl',
433
                $this->server['server']['url']."/covers/{$this->release->coverurl}"
434
            );
435
        }
436
437
        if ((int) $this->parameters['extended'] === 1) {
438
            $this->writeZedAttr('files', $this->release->totalpart);
439
            $this->writeZedAttr('poster', $this->release->fromname);
440
            if (($this->release->videos_id > 0 || $this->release->tv_episodes_id > 0) && $this->namespace === 'newznab') {
441
                $this->setTvAttr();
442
            }
443
444
            if (isset($this->release->imdbid) && $this->release->imdbid > 0) {
445
                $this->writeZedAttr('imdb', $this->release->imdbid);
446
            }
447
            if (isset($this->release->anidbid) && $this->release->anidbid > 0) {
448
                $this->writeZedAttr('anidbid', $this->release->anidbid);
449
            }
450
            if (isset($this->release->predb_id) && $this->release->predb_id > 0) {
451
                $this->writeZedAttr('prematch', 1);
452
            }
453
            if (isset($this->release->nfostatus) && (int) $this->release->nfostatus === 1) {
454
                $this->writeZedAttr(
455
                    'info',
456
                    $this->server['server']['url'].
457
                    "api?t=info&id={$this->release->guid}&r={$this->parameters['token']}"
458
                );
459
            }
460
461
            $this->writeZedAttr('grabs', $this->release->grabs);
462
            $this->writeZedAttr('comments', $this->release->comments);
463
            $this->writeZedAttr('password', $this->release->passwordstatus);
464
            $this->writeZedAttr('usenetdate', Carbon::parse($this->release->postdate)->toRssString());
465
            if (! empty($this->release->group_name)) {
466
                $this->writeZedAttr('group', $this->release->group_name);
467
            }
468
        }
469
    }
470
471
    /**
472
     * Writes the TV Specific attributes.
473
     */
474
    protected function setTvAttr(): void
475
    {
476
        if (! empty($this->release->title)) {
477
            $this->writeZedAttr('title', $this->release->title);
478
        }
479
        if (isset($this->release->series) && $this->release->series > 0) {
480
            $this->writeZedAttr('season', $this->release->series);
481
        }
482
        if (isset($this->release->episode->episode) && $this->release->episode->episode > 0) {
483
            $this->writeZedAttr('episode', $this->release->episode->episode);
484
        }
485
        if (! empty($this->release->firstaired)) {
486
            $this->writeZedAttr('tvairdate', $this->release->firstaired);
487
        }
488
        if (isset($this->release->tvdb) && $this->release->tvdb > 0) {
489
            $this->writeZedAttr('tvdbid', $this->release->tvdb);
490
        }
491
        if (isset($this->release->trakt) && $this->release->trakt > 0) {
492
            $this->writeZedAttr('traktid', $this->release->trakt);
493
        }
494
        if (isset($this->release->tvrage) && $this->release->tvrage > 0) {
495
            $this->writeZedAttr('tvrageid', $this->release->tvrage);
496
            $this->writeZedAttr('rageid', $this->release->tvrage);
497
        }
498
        if (isset($this->release->tvmaze) && $this->release->tvmaze > 0) {
499
            $this->writeZedAttr('tvmazeid', $this->release->tvmaze);
500
        }
501
        if (isset($this->release->imdb) && $this->release->imdb > 0) {
502
            $this->writeZedAttr('imdbid', $this->release->imdb);
503
        }
504
        if (isset($this->release->tmdb) && $this->release->tmdb > 0) {
505
            $this->writeZedAttr('tmdbid', $this->release->tmdb);
506
        }
507
    }
508
509
    /**
510
     * Writes individual zed (newznab) type attributes.
511
     *
512
     * @param string $name  The namespaced attribute name tag
513
     * @param string $value The namespaced attribute value
514
     */
515
    protected function writeZedAttr($name, $value): void
516
    {
517
        $this->xml->startElement($this->namespace.':attr');
518
        $this->xml->writeAttribute('name', $name);
519
        $this->xml->writeAttribute('value', $value);
520
        $this->xml->endElement();
521
    }
522
523
    /**
524
     * Writes the cData (HTML format) for the RSS feed
525
     * Also calls supplementary cData writes depending upon post process.
526
     */
527
    protected function writeRssCdata(): void
528
    {
529
        $this->cdata = "\n\t<div>\n";
530
        switch (1) {
531
            case ! empty($this->release->cover):
532
                $dir = 'movies';
533
                $column = 'imdbid';
534
                break;
535
            case ! empty($this->release->mu_cover):
536
                $dir = 'music';
537
                $column = 'musicinfo_id';
538
                break;
539
            case ! empty($this->release->co_cover):
540
                $dir = 'console';
541
                $column = 'consoleinfo_id';
542
                break;
543
            case ! empty($this->release->bo_cover):
544
                $dir = 'books';
545
                $column = 'bookinfo_id';
546
                break;
547
        }
548
        if (isset($dir, $column)) {
549
            $dcov = ($dir === 'movies' ? '-cover' : '');
550
            $this->cdata .=
551
                "\t<img style=\"margin-left:10px;margin-bottom:10px;float:right;\" ".
552
                "src=\"{$this->server['server']['url']}/covers/{$dir}/{$this->release->$column}{$dcov}.jpg\" ".
553
                "width=\"120\" alt=\"{$this->release->searchname}\" />\n";
554
        }
555
        $size = human_filesize($this->release->size);
556
        $this->cdata .=
557
            "\t<li>ID: <a href=\"{$this->server['server']['url']}/details/{$this->release->guid}\">{$this->release->guid}</a></li>\n".
558
            "\t<li>Name: {$this->release->searchname}</li>\n".
559
            "\t<li>Size: {$size}</li>\n".
560
            "\t<li>Category: <a href=\"{$this->server['server']['url']}/browse/{$this->release->category_name}\">{$this->release->category_name}</a></li>\n".
561
            "\t<li>Group: <a href=\"{$this->server['server']['url']}/browse/group?g={$this->release->group_name}\">{$this->release->group_name}</a></li>\n".
562
            "\t<li>Poster: {$this->release->fromname}</li>\n".
563
            "\t<li>Posted: {$this->release->postdate}</li>\n";
564
565
        switch ($this->release->passwordstatus) {
566
            case 0:
567
                $pstatus = 'None';
568
                break;
569
            case 1:
570
                $pstatus = 'Possibly Passworded';
571
                break;
572
            case 2:
573
                $pstatus = 'Probably not viable';
574
                break;
575
            case 10:
576
                $pstatus = 'Passworded';
577
                break;
578
            default:
579
                $pstatus = 'Unknown';
580
        }
581
        $this->cdata .= "\t<li>Password: {$pstatus}</li>\n";
582
        if ($this->release->nfostatus === 1) {
583
            $this->cdata .=
584
                "\t<li>Nfo: ".
585
                "<a href=\"{$this->server['server']['url']}/api?t=nfo&id={$this->release->guid}&raw=1&i={$this->parameters['uid']}&r={$this->parameters['token']}\">".
586
                "{$this->release->searchname}.nfo</a></li>\n";
587
        }
588
589
        if ($this->release->parentid === Category::MOVIE_ROOT && $this->release->imdbid !== '') {
590
            $this->writeRssMovieInfo();
591
        } elseif ($this->release->parentid === Category::MUSIC_ROOT && $this->release->musicinfo_id > 0) {
592
            $this->writeRssMusicInfo();
593
        } elseif ($this->release->parentid === Category::GAME_ROOT && $this->release->consoleinfo_id > 0) {
594
            $this->writeRssConsoleInfo();
595
        }
596
        $this->xml->startElement('description');
597
        $this->xml->writeCdata($this->cdata."\t</div>");
598
        $this->xml->endElement();
599
    }
600
601
    /**
602
     * Writes the Movie Info for the RSS feed cData.
603
     */
604
    protected function writeRssMovieInfo(): void
605
    {
606
        $movieCol = ['rating', 'plot', 'year', 'genre', 'director', 'actors'];
607
608
        $cData = $this->buildCdata($movieCol);
609
610
        $this->cdata .=
611
            "\t<li>Imdb Info:
612
				\t<ul>
613
					\t<li>IMDB Link: <a href=\"http://www.imdb.com/title/tt{$this->release->imdbid}/\">{$this->release->searchname}</a></li>\n
614
					\t{$cData}
615
				\t</ul>
616
			\t</li>
617
			\n";
618
    }
619
620
    /**
621
     * Writes the Music Info for the RSS feed cData.
622
     */
623
    protected function writeRssMusicInfo(): void
624
    {
625
        $tData = $cDataUrl = '';
626
627
        $musicCol = ['mu_artist', 'mu_genre', 'mu_publisher', 'mu_releasedate', 'mu_review'];
628
629
        $cData = $this->buildCdata($musicCol);
630
631
        if ($this->release->mu_url !== '') {
632
            $cDataUrl = "<li>Amazon: <a href=\"{$this->release->mu_url}\">{$this->release->mu_title}</a></li>";
633
        }
634
635
        $this->cdata .=
636
            "\t<li>Music Info:
637
			<ul>
638
			{$cDataUrl}
639
			{$cData}
640
			</ul>
641
			</li>\n";
642
        if ($this->release->mu_tracks !== '') {
643
            $tracks = explode('|', $this->release->mu_tracks);
644
            if (\count($tracks) > 0) {
645
                foreach ($tracks as $track) {
646
                    $track = trim($track);
647
                    $tData .= "<li>{$track}</li>";
648
                }
649
            }
650
            $this->cdata .= "
651
			<li>Track Listing:
652
				<ol>
653
				{$tData}
654
				</ol>
655
			</li>\n";
656
        }
657
    }
658
659
    /**
660
     * Writes the Console Info for the RSS feed cData.
661
     */
662
    protected function writeRssConsoleInfo(): void
663
    {
664
        $gamesCol = ['co_genre', 'co_publisher', 'year', 'co_review'];
665
666
        $cData = $this->buildCdata($gamesCol);
667
668
        $this->cdata .= "
669
		<li>Console Info:
670
			<ul>
671
				<li>Amazon: <a href=\"{$this->release->co_url}\">{$this->release->co_title}</a></li>\n
672
				{$cData}
673
			</ul>
674
		</li>\n";
675
    }
676
677
    /**
678
     * Accepts an array of values to loop through to build cData from the release info.
679
     *
680
     * @param array $columns The columns in the release we need to insert
681
     *
682
     * @return string The HTML format cData
683
     */
684
    protected function buildCdata($columns): string
685
    {
686
        $cData = '';
687
688
        foreach ($columns as $info) {
689
            if (! empty($this->release->$info)) {
690
                if ($info === 'mu_releasedate') {
691
                    $ucInfo = 'Released';
692
                    $rDate = date('Y-m-d', strtotime($this->release->$info));
693
                    $cData .= "<li>{$ucInfo}: {$rDate}</li>\n";
694
                } else {
695
                    $ucInfo = ucfirst(preg_replace('/^[a-z]{2}_/i', '', $info));
696
                    $cData .= "<li>{$ucInfo}: {$this->release->$info}</li>\n";
697
                }
698
            }
699
        }
700
701
        return $cData;
702
    }
703
}
704