1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
oembed.php
См. документацию.
1<?php
2
3namespace Bitrix\Main\UrlPreview\Parser;
4
5use Bitrix\Main\Text\Encoding;
6use Bitrix\Main\UrlPreview\UrlPreview;
7use Bitrix\Main\Web\HttpClient;
8use Bitrix\Main\UrlPreview\HtmlDocument;
9use Bitrix\Main\UrlPreview\Parser;
10
11class Oembed extends Parser
12{
13 const OEMBED_TYPE_XML = "text/xml+oembed";
14 const OEMBED_TYPE_JSON ="application/json+oembed";
15
17 protected $metadataType;
18
20 protected $metadataUrl;
21
24
31 public function handle(HtmlDocument $document, HttpClient $httpClient = null)
32 {
33 if(!$this->detectOembedLink($document) || $this->metadataUrl == '')
34 {
35 return;
36 }
37
38 $isHttpClientPassed = true;
39 if(!$httpClient)
40 {
41 $httpClient = $this->initHttpClient();
42 $isHttpClientPassed = false;
43 }
44 $rawMetadata = $this->getRawMetaData($httpClient);
45 // if request was served through http - try to switch to https
46 if(
47 (
48 !$rawMetadata
49 || $httpClient->getStatus() === 403
50 )
51 && str_starts_with($this->metadataUrl, 'http://'))
52 {
53 if(!$isHttpClientPassed)
54 {
55 $httpClient = $this->initHttpClient();
56 }
57 $metadataUrl = str_replace('http://', 'https://', $this->metadataUrl);
58 $rawMetadata = $httpClient->get($metadataUrl);
59 }
60
61 if($rawMetadata === false)
62 {
63 return;
64 }
65
66 $parsedMetadata = $this->parseMetadata($rawMetadata);
67 if($parsedMetadata !== false)
68 {
69 if($this->metadataEncoding <> '' && $document->getEncoding() !== $this->metadataEncoding)
70 {
71 $parsedMetadata = Encoding::convertEncoding($parsedMetadata, $this->metadataEncoding, $document->getEncoding());
72 }
73
74 if($document->getTitle() == '' && !empty($parsedMetadata['title']))
75 {
76 $document->setTitle($parsedMetadata['title']);
77 }
78
79 if($document->getImage() == '' && !empty($parsedMetadata['thumbnail_url']))
80 {
81 $image = $parsedMetadata['thumbnail_url'];
82 if (is_array($image))
83 {
84 $image = reset($image);
85 }
86 $document->setImage($image);
87 }
88
89 if($document->getEmdbed() == '' && !empty($parsedMetadata['html']))
90 {
91 $document->setEmbed($parsedMetadata['html']);
92 }
93
94 if($document->getExtraField('PROVIDER_NAME') == '' && !empty($parsedMetadata['provider_name']))
95 {
96 $document->setExtraField('PROVIDER_NAME', $parsedMetadata['provider_name']);
97 }
98
99 if($document->getExtraField('VIDEO_WIDTH') == '' && !empty($parsedMetadata['width']))
100 {
101 $document->setExtraField('VIDEO_WIDTH', $parsedMetadata['width']);
102 }
103
104 if($document->getExtraField('VIDEO_HEIGHT') == '' && !empty($parsedMetadata['height']))
105 {
106 $document->setExtraField('VIDEO_HEIGHT', $parsedMetadata['height']);
107 }
108 }
109 }
110
115 protected function detectOembedLink(HtmlDocument $document)
116 {
117 preg_match_all('/<link[^>]*rel\s*=\s*["\']?alternate["\']?[^>]*?>/', $document->getHtml(), $linkElements);
118
119 foreach($linkElements[0] as $linkElement)
120 {
121 $typeJson = (str_contains($linkElement, $this::OEMBED_TYPE_JSON));
122 $typeXml = (str_contains($linkElement, $this::OEMBED_TYPE_XML));
123 if($typeJson || $typeXml)
124 {
125 if(preg_match('/href=[\'"](.+?)[\'"]/', $linkElement, $attributes))
126 {
127 $this->metadataType = ($typeJson ? 'json' : 'xml');
128 $this->metadataUrl = htmlspecialcharsback($attributes[1]);
129 return true;
130 }
131 }
132 }
133
134 return false;
135 }
136
141 protected function parseMetadata($rawMetadata)
142 {
143 switch($this->metadataType)
144 {
145 case 'json':
146 return $this->parseJsonMetadata($rawMetadata);
147 break;
148 case 'xml':
149 return $this->parseXmlMetadata($rawMetadata);
150 break;
151 }
152
153 return false;
154 }
155
156 protected function parseJsonMetadata($rawMetadata)
157 {
158 $parsedMetadata = json_decode($rawMetadata, true);
159 $this->metadataEncoding = 'UTF-8';
160
161 return $parsedMetadata;
162 }
163
168 protected function parseXmlMetadata($rawMetadata)
169 {
170 $xml = new \CDataXML();
171 if($xml->LoadString($rawMetadata))
172 {
173 //detect xml encoding
174 if(preg_match('/<\?xml[^>]+?encoding=[\'"](.+?)[\'"]\?>/', $rawMetadata, $matches))
175 $this->metadataEncoding = $matches[1];
176 else
177 $this->metadataEncoding = 'UTF-8';
178
179 $result = array();
180 $dom = $xml->GetTree();
181 $mainNode = $dom->elementsByName('oembed');
182 foreach($mainNode[0]->children as $node)
183 {
184 $result[$node->name] = $node->content;
185 }
186 return $result;
187 }
188
189 return false;
190 }
191
192 protected function getRawMetaData(HttpClient $httpClient)
193 {
194 $rawMetadata = $httpClient->get($this->metadataUrl);
195
196 return $rawMetadata;
197 }
198
199 protected function initHttpClient(): HttpClient
200 {
201 $httpClient = new HttpClient();
202 $httpClient->setTimeout(5);
203 $httpClient->setStreamTimeout(5);
204 $httpClient->setHeader('User-Agent', UrlPreview::USER_AGENT, true);
205 $httpClient->setPrivateIp(false);
206
207 return $httpClient;
208 }
209}
getExtraField($fieldName)
Определения htmldocument.php:246
setExtraField($fieldName, $fieldValue)
Определения htmldocument.php:209
detectOembedLink(HtmlDocument $document)
Определения oembed.php:115
getRawMetaData(HttpClient $httpClient)
Определения oembed.php:192
const OEMBED_TYPE_XML
Определения oembed.php:13
parseXmlMetadata($rawMetadata)
Определения oembed.php:168
parseMetadata($rawMetadata)
Определения oembed.php:141
const OEMBED_TYPE_JSON
Определения oembed.php:14
handle(HtmlDocument $document, HttpClient $httpClient=null)
Определения oembed.php:31
parseJsonMetadata($rawMetadata)
Определения oembed.php:156
get($url)
Определения httpclient.php:204
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
htmlspecialcharsback($str)
Определения tools.php:2693
$matches
Определения index.php:22