Passed
Push — master ( a134f2...373bd7 )
by Kane
02:36
created

EmbedHtml::applyOptions()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 15
c 1
b 0
f 0
dl 0
loc 25
rs 9.4555
cc 5
nc 5
nop 2
1
<?php
2
namespace Cohensive\OEmbed;
3
4
class EmbedHtml
5
{
6
    public function __construct(
7
        protected string $type,
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

7
        /** @scrutinizer ignore-unused */ protected string $type,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
8
        protected string|array $html
0 ignored issues
show
Unused Code introduced by
The parameter $html is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

8
        /** @scrutinizer ignore-unused */ protected string|array $html

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
9
    ) {
10
    }
11
12
    /**
13
     * Returns HTML code for media provider.
14
     */
15
    public function html(array $options = [], bool $amp = false): string
16
    {
17
        if (is_array($this->html)) {
0 ignored issues
show
Bug Best Practice introduced by
The property html does not exist on Cohensive\OEmbed\EmbedHtml. Did you maybe forget to declare it?
Loading history...
18
            $attrs = $this->applyOptions($this->html, $options);
19
        }
20
21
        if ($this->type === 'iframe') {
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on Cohensive\OEmbed\EmbedHtml. Did you maybe forget to declare it?
Loading history...
22
            return $this->iframe($attrs, $amp);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $attrs does not seem to be defined for all execution paths leading up to this point.
Loading history...
23
        }
24
25
        if ($this->type === 'video') {
26
            return $this->video($attrs, $amp);
27
        }
28
29
        return $this->html;
30
    }
31
32
    /**
33
     * Return AMP-friendly HTML for media provider.
34
     *
35
     * @param array $options
36
     * @return string
37
     */
38
    public function ampHtml(array $options = []): string
39
    {
40
        return $this->html($options, true);
41
    }
42
43
    /**
44
     * Constructs <iframe> HTML-element based on array of provider attributes.
45
     */
46
    protected function iframe(array $attrs, bool $amp = false): string
47
    {
48
        $tag = $amp ? 'amp-iframe' : 'iframe';
49
50
        $html = "<$tag";
51
        foreach ($attrs as $attr => $val) {
52
            $html .= sprintf(' %s="%s"', $attr, $val);
53
        }
54
        $html .= "></$tag>";
55
56
        return $html;
57
    }
58
59
    /**
60
     * Constructs <video> HTML-element based on an array of provider attributes.
61
     *
62
     * @param array $attrs
63
     * @param boolean $amp
64
     * @return void
65
     */
66
    protected function video(array $attrs, bool $amp = false): string
67
    {
68
        $tag = $amp ? 'amp-video' : 'video';
69
70
        $inner = '';
71
72
        $html = "<$tag";
73
        foreach ($attrs as $attr => $val) {
74
            if (is_array($val)) {
75
                foreach ($val as $child) {
76
                    $inner .= "<$attr";
77
                    foreach ($child as $iattr => $ival) {
78
                        $inner .= sprintf(' %s="%s"', $iattr, $ival);
79
                    }
80
                    $inner .= ">";
81
                }
82
            } else {
83
                $html .= sprintf(' %s="%s"', $attr, $val);
84
            }
85
        }
86
        $html .= ">";
87
88
        $html .= $inner;
89
90
        $html .= "</$tag>";
91
92
        return $html;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $html returns the type string which is incompatible with the documented return type void.
Loading history...
93
    }
94
95
    /**
96
     * Converts class to an array.
97
     */
98
    public function toArray(): array
99
    {
100
        return [
101
            'type' => $this->type,
0 ignored issues
show
Bug Best Practice introduced by
The property type does not exist on Cohensive\OEmbed\EmbedHtml. Did you maybe forget to declare it?
Loading history...
102
            'html' => $this->html,
0 ignored issues
show
Bug Best Practice introduced by
The property html does not exist on Cohensive\OEmbed\EmbedHtml. Did you maybe forget to declare it?
Loading history...
103
        ];
104
    }
105
106
    /**
107
     * Extracts and returns an array of options for a current HTML element type.
108
     */
109
    protected function getTypeOptions(array $options): array
110
    {
111
        if (isset($options['html'])) {
112
            return $options['html'][$this->type] ?? [];
1 ignored issue
show
Bug Best Practice introduced by
The property type does not exist on Cohensive\OEmbed\EmbedHtml. Did you maybe forget to declare it?
Loading history...
113
        }
114
115
        return [];
116
    }
117
118
    /**
119
     * Merge and apply local and global options to the provider attributes.
120
     */
121
    protected function applyOptions(array $attrs, array $options): array
122
    {
123
        $width = $options['width'] ?? null;
124
        $height = $options['height'] ?? null;
125
126
        if (isset($attrs['width']) && isset($attrs['height'])) {
127
            $ratio = $attrs['width'] / $attrs['height'];
128
129
            if ($width) {
130
                $attrs['width'] = $width;
131
            } else {
132
                $attrs['width'] = (int) ($attrs['height'] * $ratio);
133
            }
134
135
            if ($height) {
136
                $attrs['height'] = $height;
137
            } else {
138
                $attrs['height'] = (int) ($attrs['width'] / $ratio);
139
            }
140
        }
141
142
        $typeOptions = $this->getTypeOptions($options);
143
        $attrs = array_merge($attrs, $typeOptions);
144
145
        return $attrs;
146
    }
147
}
148