Completed
Pull Request — develop (#27)
by Chris
13:09
created

Dumper::generateComponentLines()   D

Complexity

Conditions 9
Paths 13

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 4.909
c 0
b 0
f 0
cc 9
eloc 21
nc 13
nop 2
1
<?php
2
3
namespace Chrisyue\PhpM3u8\Dumper;
4
5
use Chrisyue\PhpM3u8\Model\AbstractPlaylist;
6
use Chrisyue\PhpM3u8\Model\Mapping\AttributeMetadatas;
7
use Chrisyue\PhpM3u8\Model\Mapping\TagMetadata;
8
use Chrisyue\PhpM3u8\Model\Mapping\TagMetadatas;
9
use Chrisyue\PhpM3u8\Model\MasterPlaylist;
10
use Chrisyue\PhpM3u8\Model\MediaPlaylist;
11
use Chrisyue\PhpM3u8\Model\MediaSegment;
12
use Chrisyue\PhpM3u8\Model\Tag\AbstractAttributeList;
13
14
class Dumper
15
{
16
    private $tagMetadatas;
17
    private $lines;
18
19
    public function __construct()
20
    {
21
        $this->tagMetadatas = new TagMetadatas();
22
    }
23
24
    public function dump(AbstractPlaylist $playlist)
25
    {
26
        $this->lines = ['#EXTM3U'];
27
        $this->generateComponentLines($playlist, new \ReflectionClass(AbstractPlaylist::class));
28
        $this->generateComponentLines($playlist, new \ReflectionClass($playlist instanceof MediaPlaylist ? MediaPlaylist::class : MasterPlaylist::class));
29
30
        return implode("\n", $this->lines);
31
    }
32
33
    private function generateComponentLines($component, \ReflectionClass $refClass)
34
    {
35
        foreach ($refClass->getProperties() as $refProp) {
36
            $refProp->setAccessible(true);
37
            if ('segments' === $refProp->getName()) {
38
                $refMs = new \ReflectionClass(MediaSegment::class);
39
                foreach ($refProp->getValue($component) as $segment) {
40
                    $this->generateComponentLines($segment, $refMs);
41
                }
42
43
                continue;
44
            }
45
46
            if ('uri' === $refProp->getName()) {
47
                $this->lines[] = $component->uri;
48
            }
49
50
            $metadata = $this->tagMetadatas->getByPropertyName($refProp->getName());
51
            if (!$metadata) {
52
                continue;
53
            }
54
55
            $value = $refProp->getValue($component);
56
            if (!$value) {
57
                continue;
58
            }
59
60
            if ($metadata->isMultiple()) {
61
                foreach ($value as $val) {
62
                    $this->lines[] = $this->createLine($metadata, $val);
63
                }
64
                continue;
65
            }
66
67
            $this->lines[] = $this->createLine($metadata, $value);
68
        }
69
    }
70
71
    private function createLine(TagMetadata $metadata, $value)
72
    {
73
        $line = $metadata->getName();
74
        if (true === $value) {
75
            return sprintf('#%s', $line);
76
        }
77
78
        if (!$value instanceof AbstractAttributeList) {
79
            return sprintf('#%s:%s', $line, $value);
80
        }
81
82
        $attrMetadatas = new AttributeMetadatas($metadata->getType());
83
        $attrs = [];
84
        foreach ($attrMetadatas as $attrMetadata) {
85
            $name = $attrMetadata->getName();
86
            $val = $attrMetadata->getProperty()->getValue($value);
87
            if (null === $val) {
88
                continue;
89
            }
90
91
            if ('string' === $attrMetadata->getType()) {
92
                $val = sprintf('"%s"', $val);
93
            }
94
            $attrs[] = sprintf('%s=%s', $name, $val);
95
        }
96
97
        return sprintf('#%s:%s', $line, implode(',', $attrs));
98
    }
99
}
100