Passed
Push — master ( 741733...9f2f63 )
by Kane
02:52 queued 17s
created

Embed::mediaType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
namespace Cohensive\OEmbed;
3
4
use DOMDocument;
5
6
class Embed
7
{
8
    const TYPE_OEMBED = 0;
9
10
    const TYPE_REGEX = 1;
11
12
    /**
13
     * Type of an Embed object source data - OEmbed or Regex-based.
14
     */
15
    protected int $type;
16
17
    /**
18
     * Array of global options applied to embed objects.
19
     */
20
    protected array $options;
21
22
    /**
23
     * Original media URL.
24
     */
25
    protected string $url;
26
27
    /**
28
     * Embed data extracted via OEmbed or Regex extractors.
29
     */
30
    protected array $data;
31
32
    /**
33
     * Class containing Embed HTML code.
34
     */
35
    protected EmbedHtml $html;
36
37
    /**
38
     * Thumbnail data if available.
39
     */
40
    protected ?array $thumbnail;
41
42
    /**
43
     * Creates Embed instance.
44
     */
45
    public function __construct(
46
        string $type,
47
        string $url,
48
        array $data,
49
        array $options = [],
50
        bool $amp = false
51
    ) {
52
        $this->type = $type;
53
        $this->url = $url;
54
        $this->data = $data;
55
        $this->options = $options;
56
        $this->amp = $amp;
0 ignored issues
show
Bug Best Practice introduced by
The property amp does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
57
58
        $this->initData($data);
59
    }
60
61
    /**
62
     * Initializer for the Embed object filling thumbnail, html and type based
63
     * on a given media provider data.
64
     */
65
    public function initData(array $data): self
66
    {
67
        if (isset($data['thumbnail_url'])) {
68
            $this->thumbnail = [
69
                'url' => $data['thumbnail_url'],
70
                'width' => $data['thumbnail_width'] ?? null,
71
                'height' => $data['thumbnail_height'] ?? null,
72
            ];
73
        }
74
75
        if ($this->type == self::TYPE_OEMBED) {
76
            $this->html = $this->extractOEmbedHtml($data['html']);
77
        } else {
78
            $this->html = $this->extractRegexHtml($data['html']);
79
        }
80
81
        return $this;
82
    }
83
84
    /**
85
     * Returns mbed options.
86
     */
87
    public function getOptions(): array
88
    {
89
        return $this->options;
90
    }
91
92
    /**
93
     * Sets new embed options. See config file 'options' key.
94
     */
95
    public function setOptions(array $options): self
96
    {
97
        $this->options = $options;
98
        return $this;
99
    }
100
101
    /**
102
     * Sets AMP mode.
103
     */
104
    public function setAmp(bool $amp): self
105
    {
106
        $this->amp = $amp;
0 ignored issues
show
Bug Best Practice introduced by
The property amp does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
107
        return $this;
108
    }
109
110
    /**
111
     * Returns string with HTML to embed in application. Will return AMP-friendly
112
     * HTML if global amp mode is enabled and not overwitten.
113
     */
114
    public function html(array $options = null, ?bool $amp = null): string
115
    {
116
        if (is_null($options)) {
117
            $options = $this->options;
118
        } else {
119
            $options = array_merge($this->options, $options);
120
        }
121
122
        if (is_null($amp)) {
123
            $amp = $this->amp;
124
        }
125
126
        return $this->html->html($options, $amp);
127
    }
128
129
    /**
130
     * Returns string with AMP-friendly HTML to embed in an application.
131
     *
132
     * @param array $options
133
     * @return string
134
     */
135
    public function ampHtml(array $options = null): string
136
    {
137
        return $this->html($options, true);
138
    }
139
140
    /**
141
     * Returns embed provider type.
142
     */
143
    public function type(): int
144
    {
145
        return $this->type;
146
    }
147
148
    /**
149
     * Returns media provider data.
150
     */
151
    public function url(): string
152
    {
153
        return $this->url;
154
    }
155
156
    /**
157
     * Returns media provider data.
158
     */
159
    public function data(): array
160
    {
161
        return $this->data;
162
    }
163
164
    /**
165
     * Returns string describing media type. According to OEmbed spec it could be:
166
     * one of these: photo, video, link, rich
167
     */
168
    public function mediaType(): string
169
    {
170
        return $this->data['type'];
171
    }
172
173
    /**
174
     * Returns boolean flag telling if given embed data has a thumbnail.
175
     */
176
    public function hasThumbnail(): bool
177
    {
178
        return is_array($this->thumbnail);
179
    }
180
181
    /**
182
     * Returns thumbnail data in an array form containing url and its dimensions.
183
     *
184
     * @return array|null
185
     */
186
    public function thumbnail(): ?array
187
    {
188
        return $this->thumbnail;
189
    }
190
191
    /**
192
     * Reutrns string for thumbnail or null if it's not set.
193
     */
194
    public function thumbnailUrl(): ?string
195
    {
196
        return $this->hasThumbnail() ? $this->thumbnail['url'] : null;
197
    }
198
199
    /**
200
     * Return thumbnail width or 0 if not set.
201
     */
202
    public function thumbnailWidth(): int
203
    {
204
        return $this->hasThumbnail() ? $this->thumbnail['width'] : 0;
205
    }
206
207
    /**
208
     * Return thumbnail height or 0 if not set.
209
     */
210
    public function thumbnailHeight(): int
211
    {
212
        return $this->hasThumbnail() ? $this->thumbnail['height'] : 0;
213
    }
214
215
    /**
216
     * Converts Embed instance into an array for caching.
217
     */
218
    public function toArray(): array
219
    {
220
        return [
221
            'type' => $this->type,
222
            'url' => $this->url,
223
            'data' => $this->data,
224
        ];
225
    }
226
227
    /**
228
     * Converts Embed instance into json string.
229
     *
230
     * @return string
231
     */
232
    public function toJson(): string
233
    {
234
        return json_encode($this->toArray());
235
    }
236
237
    /**
238
     * Returns EmbedHtml instance of OEmbed media provider HTML string.
239
     */
240
    protected function extractOEmbedHtml(string $html): EmbedHtml
241
    {
242
        $doc = new DOMDocument();
243
        $doc->loadHTML('<html><body>' . $html . '</body></html>');
244
        $body = $doc->getElementsByTagName('body')[0];
245
246
        if ($body->firstChild->nodeName === 'iframe') {
247
            $attrs = [];
248
249
            foreach ($body->firstChild->attributes as $attribute) {
250
                $attrs[$attribute->name] = $attribute->value;
251
            }
252
253
            return new EmbedHtml('iframe', $attrs);
254
        }
255
256
        return new EmbedHtml('html', $html);
257
    }
258
259
    /**
260
     * Returns EmbedHtml instance of Regex media provider HTML string.
261
     */
262
    protected function extractRegexHtml(array $html): EmbedHtml
263
    {
264
        $type = array_key_first($html);
265
        return new EmbedHtml($type, $html[$type]);
266
    }
267
}
268