Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
urlpreview.php
1<?php
2
4
16
18{
19 const SIGN_SALT = 'url_preview';
20 const USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 (Bitrix link preview)';
22 const MAX_DESCRIPTION = 500;
24 const MAX_FILE_SIZE = 1048576;
26 const FILE_RANGE = 1023;
27
28 const IFRAME_MAX_WIDTH = 640;
29 const IFRAME_MAX_HEIGHT = 340;
30
31 protected static $trustedHosts = [
32 'youtube.com' => 'youtube.com',
33 'youtu.be' => 'youtu.be',
34 'vimeo.com' => 'vimeo.com',
35 'rutube.ru' => 'rutube.ru',
36 'facebook.com' => 'facebook.com',
37 'fb.watch' => 'fb.watch',
38 'vk.com' => 'vk.com',
39 'instagram.com' => 'instagram.com',
40 ];
41
50 public static function getMetadataByUrl($url, $addIfNew = true, $reuseExistingMetadata = true)
51 {
52 if (!static::isEnabled())
53 {
54 return false;
55 }
56
57 $url = static::normalizeUrl($url);
58 if ($url == '')
59 {
60 return false;
61 }
62
63 if ($reuseExistingMetadata)
64 {
65 if ($metadata = UrlMetadataTable::getByUrl($url))
66 {
67 if ($metadata['TYPE'] === UrlMetadataTable::TYPE_TEMPORARY && $addIfNew)
68 {
69 $metadata = static::resolveTemporaryMetadata($metadata['ID']);
70 return $metadata;
71 }
72 if ($metadata['TYPE'] !== UrlMetadataTable::TYPE_STATIC
73 || !isset($metadata['DATE_EXPIRE'])
74 || $metadata['DATE_EXPIRE']->getTimestamp() > time()
75 )
76 {
77 return $metadata;
78 }
79 if (static::refreshMetadata($metadata))
80 {
81 return $metadata;
82 }
83 }
84 }
85
86 if (!$addIfNew)
87 {
88 return false;
89 }
90
91 $metadataId = static::reserveIdForUrl($url);
92 $metadata = static::fetchUrlMetadata($url);
93 if (is_array($metadata) && !empty($metadata))
94 {
95 $result = UrlMetadataTable::update($metadataId, $metadata);
96 $metadata['ID'] = $result->getId();
97 return $metadata;
98 }
99
100 return false;
101 }
102
112 public static function showView($userField, $userFieldParams, &$cacheTag, $edit = false)
113 {
114 global $APPLICATION;
115 $edit = !!$edit;
116 $cacheTag = '';
117
118 if (!static::isEnabled())
119 {
120 return null;
121 }
122
123 $metadataId = (int)$userField['VALUE'][0];
124 $metadata = false;
125 if ($metadataId > 0)
126 {
127 $metadata = UrlMetadataTable::getById($metadataId)->fetch();
128 if (isset($metadata['TYPE']) && $metadata['TYPE'] == UrlMetadataTable::TYPE_TEMPORARY)
129 {
130 $metadata = static::resolveTemporaryMetadata($metadata['ID']);
131 }
132 }
133
134 if (is_array($metadata))
135 {
136 $fullUrl = static::unfoldShortLink($metadata['URL']);
137 if ($metadata['TYPE'] == UrlMetadataTable::TYPE_DYNAMIC)
138 {
139 $routeRecord = Router::dispatch(new Uri($fullUrl));
140
141 if (isset($routeRecord['MODULE']) && Loader::includeModule($routeRecord['MODULE']))
142 {
143 $className = $routeRecord['CLASS'];
144 $routeRecord['PARAMETERS']['URL'] = $metadata['URL'];
145 $parameters = $routeRecord['PARAMETERS'];
146
147 if ($edit && (!method_exists($className, 'checkUserReadAccess') || !$className::checkUserReadAccess($parameters, static::getCurrentUserId())))
148 {
149 return null;
150 }
151
152 if (method_exists($className, 'buildPreview'))
153 {
154 $metadata['HANDLER'] = $routeRecord;
155 $metadata['HANDLER']['BUILD_METHOD'] = 'buildPreview';
156 }
157
158 if (method_exists($className, 'getCacheTag'))
159 {
160 $cacheTag = $className::getCacheTag();
161 }
162 }
163 elseif (!$edit)
164 {
165 return null;
166 }
167 }
168 }
169 elseif (!$edit)
170 {
171 return null;
172 }
173
174 ob_start();
175 $APPLICATION->IncludeComponent(
176 'bitrix:main.urlpreview',
177 '',
178 array(
179 'USER_FIELD' => $userField,
180 'METADATA' => is_array($metadata) ? $metadata : [],
181 'PARAMS' => $userFieldParams,
182 'EDIT' => ($edit ? 'Y' : 'N'),
183 'CHECK_ACCESS' => ($edit ? 'Y' : 'N'),
184 )
185 );
186 return ob_get_clean();
187 }
188
196 public static function showEdit($userField, $userFieldParams)
197 {
198 return static::showView($userField, $userFieldParams, $cacheTag, true);
199 }
200
207 public static function isUrlCached($url)
208 {
209 $url = static::normalizeUrl($url);
210 if ($url == '')
211 {
212 return false;
213 }
214
215 return (static::isUrlLocal(new Uri($url)) || !!UrlMetadataTable::getByUrl($url));
216 }
217
227 public static function getMetadataAndHtmlByUrl($url, $addIfNew = true, $reuseExistingMetadata = true)
228 {
229 $metadata = static::getMetadataByUrl($url, $addIfNew, $reuseExistingMetadata);
230 if ($metadata === false)
231 {
232 return false;
233 }
234
235 if ($metadata['TYPE'] == UrlMetadataTable::TYPE_STATIC || $metadata['TYPE'] == UrlMetadataTable::TYPE_FILE)
236 {
237 return $metadata;
238 }
239 elseif ($metadata['TYPE'] == UrlMetadataTable::TYPE_DYNAMIC)
240 {
241 if ($preview = static::getDynamicPreview($url))
242 {
243 $metadata['HTML'] = $preview;
244 return $metadata;
245 }
246
247 }
248
249 return false;
250 }
251
260 public static function getMetadataAndHtmlByIds(array $ids, $checkAccess = true, $userId = 0)
261 {
262 if (!static::isEnabled())
263 {
264 return false;
265 }
266
267 $result = [];
268
269 $queryResult = UrlMetadataTable::getList([
270 'filter' => [
271 'ID' => $ids,
273 ]
274 ]);
275
276 while ($metadata = $queryResult->fetch())
277 {
278 if ($metadata['TYPE'] == UrlMetadataTable::TYPE_DYNAMIC)
279 {
280 $metadata['HTML'] = static::getDynamicPreview($metadata['URL'], $checkAccess, $userId);
281 if ($metadata['HTML'] === false)
282 {
283 continue;
284 }
285 }
286 if ($metadata['TYPE'] == UrlMetadataTable::TYPE_STATIC
287 && isset($metadata['DATE_EXPIRE'])
288 && $metadata['DATE_EXPIRE']->getTimestamp() <= time()
289 )
290 {
291 $refreshResult = static::refreshMetadata($metadata);
292 if (!$refreshResult)
293 {
294 continue;
295 }
296 }
297 $result[$metadata['ID']] = $metadata;
298 }
299
300 return $result;
301 }
302
303 public static function getMetadataByIds(array $ids)
304 {
305 if (!static::isEnabled())
306 {
307 return false;
308 }
309
310 $result = [];
311
312 $queryResult = UrlMetadataTable::getList([
313 'filter' => [
314 'ID' => $ids,
316 ]
317 ]);
318
319 while ($metadata = $queryResult->fetch())
320 {
321 if ($metadata['TYPE'] == UrlMetadataTable::TYPE_STATIC
322 && isset($metadata['DATE_EXPIRE'])
323 && $metadata['DATE_EXPIRE']->getTimestamp() <= time()
324 )
325 {
326 $refreshResult = static::refreshMetadata($metadata);
327 if (!$refreshResult)
328 {
329 continue;
330 }
331 }
332 $result[$metadata['ID']] = $metadata;
333 }
334
335 return $result;
336 }
337
344 public static function reserveIdForUrl($url)
345 {
346 if ($metadata = UrlMetadataTable::getByUrl($url))
347 {
348 $id = $metadata['ID'];
349 }
350 else
351 {
352 $result = UrlMetadataTable::add(array(
353 'URL' => $url,
355 ));
356 $id = $result->getId();
357 }
358
359 return $id;
360 }
361
370 public static function resolveTemporaryMetadata($id, $checkAccess = true, $userId = 0)
371 {
372 $metadata = UrlMetadataTable::getRowById($id);
373 if (!is_array($metadata))
374 {
375 return false;
376 }
377
378 if ($metadata['TYPE'] == UrlMetadataTable::TYPE_TEMPORARY)
379 {
380 $metadata['URL'] = static::normalizeUrl($metadata['URL']);
381 $metadata = static::fetchUrlMetadata($metadata['URL']);
382 if ($metadata === false)
383 {
384 UrlMetadataTable::delete($id);
385 return false;
386 }
387
388 UrlMetadataTable::update($id, $metadata);
389 return $metadata;
390 }
391 elseif ($metadata['TYPE'] == UrlMetadataTable::TYPE_STATIC || $metadata['TYPE'] == UrlMetadataTable::TYPE_FILE)
392 {
393 return $metadata;
394 }
395 elseif ($metadata['TYPE'] == UrlMetadataTable::TYPE_DYNAMIC)
396 {
397 if ($preview = static::getDynamicPreview($metadata['URL'], $checkAccess, $userId))
398 {
399 $metadata['HTML'] = $preview;
400 return $metadata;
401 }
402 }
403
404 return false;
405 }
406
407 protected static function refreshMetadata(array &$metadata): bool
408 {
409 if ($metadata['TYPE'] !== UrlMetadataTable::TYPE_STATIC)
410 {
411 return false;
412 }
413 $url = static::normalizeUrl($metadata['URL']);
414 $refreshedMetadata = static::fetchUrlMetadata($url);
415 if (!$refreshedMetadata)
416 {
417 return false;
418 }
419 if ($metadata['ID'])
420 {
421 UrlMetadataTable::update($metadata['ID'], $refreshedMetadata);
422 $refreshedMetadata['ID'] = $metadata['ID'];
423 }
424 $metadata = $refreshedMetadata;
425
426 return true;
427 }
428
436 public static function getDynamicPreview($url, $checkAccess = true, $userId = 0)
437 {
438 $routeRecord = Router::dispatch(new Uri(static::unfoldShortLink($url)));
439 if ($routeRecord === false)
440 {
441 return false;
442 }
443
444 if (isset($routeRecord['MODULE']) && Loader::includeModule($routeRecord['MODULE']))
445 {
446 $className = $routeRecord['CLASS'];
447 $parameters = $routeRecord['PARAMETERS'];
448 $parameters['URL'] = $url;
449
450 if ($userId == 0)
451 {
452 $userId = static::getCurrentUserId();
453 }
454
455 if ($checkAccess && (!method_exists($className, 'checkUserReadAccess') || $userId == 0 || !$className::checkUserReadAccess($parameters, $userId)))
456 return false;
457
458 if (method_exists($className, 'buildPreview'))
459 {
460 $preview = $className::buildPreview($parameters);
461 return ($preview <> '' ? $preview : false);
462 }
463 }
464 return false;
465 }
466
474 public static function getImAttach($url, $checkAccess = true, $userId = 0)
475 {
476 return self::getUrlInfoFromExternal($url, 'getImAttach', $checkAccess, $userId);
477 }
478
485 public static function getImRich($url, $checkAccess = true, $userId = 0)
486 {
487 return self::getUrlInfoFromExternal($url, 'getImRich', $checkAccess, $userId);
488 }
489
496 public static function checkDynamicPreviewAccess($url, $userId = 0)
497 {
498 $routeRecord = Router::dispatch(new Uri(static::unfoldShortLink($url)));
499 if ($routeRecord === false)
500 {
501 return false;
502 }
503
504 if (isset($routeRecord['MODULE']) && Loader::includeModule($routeRecord['MODULE']))
505 {
506 $className = $routeRecord['CLASS'];
507 $parameters = $routeRecord['PARAMETERS'];
508
509 if ($userId == 0)
510 {
511 $userId = static::getCurrentUserId();
512 }
513
514 return (method_exists($className, 'checkUserReadAccess') && $userId > 0 && $className::checkUserReadAccess($parameters, $userId));
515 }
516 return false;
517 }
518
526 public static function setMetadataImage($id, $imageUrl)
527 {
528 if (!is_int($id))
529 {
530 throw new ArgumentException("Id of the metadata must be an integer", "id");
531 }
532 if (!is_string($imageUrl) && !is_null($imageUrl))
533 {
534 throw new ArgumentException("Url of the image must be a string", "imageUrl");
535 }
536
537 $metadata = UrlMetadataTable::getList(array(
538 'select' => array('IMAGE', 'IMAGE_ID', 'EXTRA'),
539 'filter' => array('=ID' => $id)
540 ))->fetch();
541
542 if (isset($metadata['EXTRA']['IMAGES']))
543 {
544 $imageIndex = array_search($imageUrl, $metadata['EXTRA']['IMAGES']);
545 if ($imageIndex === false)
546 {
547 unset($metadata['EXTRA']['SELECTED_IMAGE']);
548 }
549 else
550 {
551 $metadata['EXTRA']['SELECTED_IMAGE'] = $imageIndex;
552 }
553 }
554
555 static::fetchImageMetadata($imageUrl, $metadata);
556
557 return UrlMetadataTable::update($id, $metadata)->isSuccess();
558 }
559
564 public static function isEnabled()
565 {
566 static $result = null;
567 if (is_null($result))
568 {
569 $result = Option::get('main', 'url_preview_enable', 'N') === 'Y';
570 }
571 return $result;
572 }
573
580 public static function sign($id)
581 {
582 $signer = new Signer();
583 return $signer->sign((string)$id, static::SIGN_SALT);
584 }
585
586 protected static function getUrlInfoFromExternal($url, $method, $checkAccess = true, $userId = 0)
587 {
588 //todo: caching
589 $routeRecord = Router::dispatch(new Uri(static::unfoldShortLink($url)));
590 if ($routeRecord === false)
591 {
592 return false;
593 }
594
595 if ($userId == 0)
596 {
597 $userId = static::getCurrentUserId();
598 }
599
600 if (isset($routeRecord['MODULE']) && Loader::includeModule($routeRecord['MODULE']))
601 {
602 $className = $routeRecord['CLASS'];
603 $parameters = $routeRecord['PARAMETERS'];
604 $parameters['URL'] = $url;
605
606 if ($checkAccess && (!method_exists($className, 'checkUserReadAccess') || $userId == 0 || !$className::checkUserReadAccess($parameters, $userId)))
607 return false;
608
609 if (method_exists($className, $method))
610 {
611 return $className::$method($parameters);
612 }
613 }
614 return false;
615 }
616
621 protected static function fetchUrlMetadata($url)
622 {
623 $fullUrl = static::unfoldShortLink($url);
624 $uriParser = new Uri($fullUrl);
625 if (static::isUrlLocal($uriParser))
626 {
627 if (Router::dispatch($uriParser))
628 {
629 $metadata = array(
630 'URL' => $url,
632 );
633 }
634 }
635 else
636 {
637 $metadataRemote = static::getRemoteUrlMetadata($uriParser);
638 if (is_array($metadataRemote) && !empty($metadataRemote))
639 {
640 $metadata = array(
641 'URL' => $url,
642 'TYPE' => $metadataRemote['TYPE'] ?? UrlMetadataTable::TYPE_STATIC,
643 'TITLE' => $metadataRemote['TITLE'] ?? '',
644 'DESCRIPTION' => $metadataRemote['DESCRIPTION'] ?? '',
645 'IMAGE_ID' => $metadataRemote['IMAGE_ID'] ?? null,
646 'IMAGE' => $metadataRemote['IMAGE'] ?? null,
647 'EMBED' => $metadataRemote['EMBED'] ?? null,
648 'EXTRA' => $metadataRemote['EXTRA'] ?? null,
649 'DATE_EXPIRE' => $metadataRemote['DATE_EXPIRE'] ?? null,
650 );
651 }
652 }
653
654 if (isset($metadata['TYPE']))
655 {
656 return $metadata;
657 }
658 return false;
659 }
660
667 protected static function isUrlLocal(Uri $uri)
668 {
669 if ($uri->getHost() == '')
670 {
671 return true;
672 }
673
674 $host = \Bitrix\Main\Context::getCurrent()->getRequest()->getHttpHost();
675 return $uri->getHost() === $host;
676 }
677
682 protected static function getRemoteUrlMetadata(Uri $uri)
683 {
684 $httpClient = (new HttpClient())
685 ->setPrivateIp(false) //prevents proxy to LAN
686 ->setTimeout(5)
687 ->setStreamTimeout(5)
688 ->setHeader('User-Agent', self::USER_AGENT)
689 ;
690
691 $httpClient->shouldFetchBody(function (Response $response) {
692 $contentType = $response->getHeadersCollection()->getContentType();
693 return ($contentType === 'text/html' || MimeType::isImage($contentType));
694 });
695
696 try
697 {
698 if (!$httpClient->query('GET', $uri->getUri()))
699 {
700 return false;
701 }
702 }
703 catch (\ErrorException)
704 {
705 return false;
706 }
707
708 if ($httpClient->getStatus() !== 200)
709 {
710 return false;
711 }
712
713 $peerIpAddress = $httpClient->getPeerAddress();
714
715 if ($httpClient->getHeaders()->getContentType() !== 'text/html')
716 {
717 $metadata = static::getFileMetadata($httpClient);
718 $metadata['EXTRA']['PEER_IP_ADDRESS'] = $peerIpAddress;
719 $metadata['EXTRA']['PEER_IP_PRIVATE'] = (new IpAddress($peerIpAddress))->isPrivate();
720
721 return $metadata;
722 }
723
724 $html = $httpClient->getResult();
725
726 $htmlDocument = new HtmlDocument($html, $uri);
727 $htmlDocument->setEncoding($httpClient->getCharset());
728 ParserChain::extractMetadata($htmlDocument);
729 $metadata = $htmlDocument->getMetadata();
730
731 if (is_array($metadata) && static::validateRemoteMetadata($metadata))
732 {
733 if (isset($metadata['IMAGE']))
734 {
735 static::fetchImageMetadata($metadata['IMAGE'], $metadata);
736 }
737
738 if (isset($metadata['DESCRIPTION']) && mb_strlen($metadata['DESCRIPTION']) > static::MAX_DESCRIPTION)
739 {
740 $metadata['DESCRIPTION'] = mb_substr($metadata['DESCRIPTION'], 0, static::MAX_DESCRIPTION);
741 }
742
743 if (!isset($metadata['EXTRA']) || !is_array($metadata['EXTRA']))
744 {
745 $metadata['EXTRA'] = array();
746 }
747
748 $metadata['EXTRA'] = array_merge($metadata['EXTRA'], array(
749 'PEER_IP_ADDRESS' => $peerIpAddress,
750 'PEER_IP_PRIVATE' => (new IpAddress($peerIpAddress))->isPrivate(),
751 'X_FRAME_OPTIONS' => $httpClient->getHeaders()->get('X-Frame-Options', true),
752 'EFFECTIVE_URL' => $httpClient->getEffectiveUrl(),
753 ));
754
755 return $metadata;
756 }
757
758 return false;
759 }
760
761 protected static function getTempPath(string $fileName): string
762 {
763 $tempFileName = Random::getString(32) . '.' . GetFileExtension($fileName);
764 $tempPath = \CFile::GetTempName('', $tempFileName);
765
766 return $tempPath;
767 }
768
769 protected static function downloadFile(string $url, ?string &$fileName = null, ?int $range = null): ?string
770 {
771 $httpClient = (new HttpClient())
772 ->setPrivateIp(false)
773 ->setTimeout(5)
774 ->setStreamTimeout(5)
775 ->setBodyLengthMax(self::MAX_FILE_SIZE)
776 ;
777
778 if ($range !== null)
779 {
780 $httpClient->setHeader('Range', 'bytes=0-' . $range);
781 }
782
783 $urlComponents = parse_url($url);
784 $fileName = ($urlComponents && $urlComponents["path"] <> '')
785 ? bx_basename($urlComponents["path"])
786 : bx_basename($url)
787 ;
788
789 $tempPath = static::getTempPath($fileName);
790
791 try
792 {
793 if (!$httpClient->download($url, $tempPath))
794 {
795 return null;
796 }
797 }
798 catch (\ErrorException)
799 {
800 return null;
801 }
802
803 if (($name = $httpClient->getHeaders()->getFilename()) !== null)
804 {
805 $fileName = $name;
806 }
807
808 return $tempPath;
809 }
810
816 protected static function saveImage(string $tempPath, ?string $fileName)
817 {
818 $fileId = false;
819
820 $localFile = \CFile::MakeFileArray($tempPath);
821
822 if (is_array($localFile))
823 {
824 $localFile['MODULE_ID'] = 'main';
825
826 if ($fileName <> '')
827 {
828 $localFile['name'] = $fileName;
829 }
830 if (\CFile::CheckImageFile($localFile, 0, 0, 0, array("IMAGE")) === null)
831 {
832 $fileId = \CFile::SaveFile($localFile, 'urlpreview', true);
833 }
834 }
835
836 return ($fileId === false ? null : $fileId);
837 }
838
839 protected static function fetchImageMetadata(string $imageUrl, array &$metadata): void
840 {
841 $saveImage = static::getOptionSaveImages();
842
843 $tempPath = static::downloadFile($imageUrl, $fileName, ($saveImage ? null : self::FILE_RANGE));
844
845 if ($tempPath !== null)
846 {
847 $info = (new Image($tempPath))->getInfo();
848 if ($info)
849 {
850 $metadata['EXTRA']['IMAGE_INFO'] = [
851 'WIDTH' => $info->getWidth(),
852 'HEIGHT' => $info->getHeight(),
853 ];
854 }
855
856 if ($saveImage)
857 {
858 $metadata['IMAGE_ID'] = static::saveImage($tempPath, $fileName);
859 $metadata['IMAGE'] = null;
860 }
861 else
862 {
863 $metadata['IMAGE'] = $imageUrl;
864 $metadata['IMAGE_ID'] = null;
865 }
866 }
867 }
868
875 protected static function normalizeUrl($url)
876 {
877 if (str_starts_with($url, 'https://') || str_starts_with($url, 'http://'))
878 {
879 //nop
880 }
881 elseif (str_starts_with($url, '//'))
882 {
883 $url = 'http:'.$url;
884 }
885 elseif (str_starts_with($url, '/'))
886 {
887 //nop
888 }
889 else
890 {
891 $url = 'http://'.$url;
892 }
893
894 $parsedUrl = new Uri($url);
895 $parsedUrl->setHost(mb_strtolower($parsedUrl->getHost()));
896
897 return $parsedUrl->getUri();
898 }
899
904 protected static function getOptionSaveImages()
905 {
906 static $result = null;
907 if (is_null($result))
908 {
909 $result = Option::get('main', 'url_preview_save_images', 'N') === 'Y';
910 }
911 return $result;
912 }
913
919 protected static function validateRemoteMetadata(array $metadata)
920 {
921 $result = ((isset($metadata['TITLE']) && isset($metadata['IMAGE'])) || (isset($metadata['TITLE']) && isset($metadata['DESCRIPTION'])) || isset($metadata['EMBED']));
922 return $result;
923 }
924
929 public static function getCurrentUserId()
930 {
931 return ($GLOBALS['USER'] instanceof \CUser) ? (int)$GLOBALS['USER']->getId() : 0;
932 }
933
939 protected static function unfoldShortLink($shortUrl)
940 {
941 static $cache = [];
942 if (isset($cache[$shortUrl]))
943 {
944 return $cache[$shortUrl];
945 }
946
947 $result = $shortUrl;
948 if ($shortUri = \CBXShortUri::GetUri($shortUrl))
949 {
950 $result = $shortUri['URI'];
951 }
952 $cache[$shortUrl] = $result;
953 return $result;
954 }
955
961 protected static function getFileMetadata(HttpClient $client)
962 {
963 $url = $client->getEffectiveUrl();
964 $httpHeaders = $client->getHeaders();
965
966 $mimeType = $httpHeaders->getContentType();
967 $filename = $httpHeaders->getFilename() ?: bx_basename($url);
968 $result = false;
969 if ($mimeType && $filename)
970 {
971 $result = array(
973 'EXTRA' => array(
974 'ATTACHMENT' => strtolower($httpHeaders->getContentDisposition()) === 'attachment' ? 'Y' : 'N',
975 'MIME_TYPE' => $mimeType,
976 'FILENAME' => $filename,
977 'SIZE' => $httpHeaders->get('Content-Length')
978 )
979 );
980
981 if (MimeType::isImage($mimeType))
982 {
983 // download image to temp file to detect dimensions
984 $tempPath = static::getTempPath($filename);
985
986 $client->saveFile($tempPath);
987
988 $info = (new Image($tempPath))->getInfo();
989 if ($info)
990 {
991 $result['EXTRA']['IMAGE_INFO'] = [
992 'WIDTH' => $info->getWidth(),
993 'HEIGHT' => $info->getHeight(),
994 ];
995 }
996 }
997 }
998 return $result;
999 }
1000
1006 public static function isIpAddressPrivate($ipAddress)
1007 {
1008 return (new IpAddress($ipAddress))->isPrivate();
1009 }
1010
1017 public static function isHostTrusted(Uri $uri)
1018 {
1019 $result = false;
1020 $domainNameParts = explode('.', $uri->getHost());
1021 if (is_array($domainNameParts) && ($partsCount = count($domainNameParts)) >= 2)
1022 {
1023 $domainName = $domainNameParts[$partsCount-2] . '.' . $domainNameParts[$partsCount-1];
1024 $result = isset(static::$trustedHosts[$domainName]);
1025 }
1026 return $result;
1027 }
1028
1035 public static function fetchVideoMetaData($url)
1036 {
1037 $url = static::unfoldShortLink($url);
1038 $uri = new Uri($url);
1039 if (static::isHostTrusted($uri) || static::isEnabled())
1040 {
1041 $url = static::normalizeUrl($url);
1042 $metadataId = static::reserveIdForUrl($url);
1043 $metadata = static::fetchUrlMetadata($url);
1044 if (is_array($metadata) && !empty($metadata))
1045 {
1046 $result = UrlMetadataTable::update($metadataId, $metadata);
1047 $metadata['ID'] = $result->getId();
1048 }
1049 else
1050 {
1051 return false;
1052 }
1053 if (!empty($metadata['EMBED']) && !str_contains($metadata['EMBED'], '<iframe'))
1054 {
1055 $url = static::getInnerFrameUrl($metadata['ID'], $metadata['EXTRA']['PROVIDER_NAME']);
1056 if (intval($metadata['EXTRA']['VIDEO_WIDTH']) <= 0)
1057 {
1058 $metadata['EXTRA']['VIDEO_WIDTH'] = self::IFRAME_MAX_WIDTH;
1059 }
1060 if (intval($metadata['EXTRA']['VIDEO_HEIGHT']) <= 0)
1061 {
1062 $metadata['EXTRA']['VIDEO_HEIGHT'] = self::IFRAME_MAX_HEIGHT;
1063 }
1064 $metadata['EMBED'] = '<iframe src="'.$url.'" allowfullscreen="" width="'.$metadata['EXTRA']['VIDEO_WIDTH'].'" height="'.$metadata['EXTRA']['VIDEO_HEIGHT'].'" frameborder="0"></iframe>';
1065 }
1066
1067 if ($metadata['EMBED'] || !empty($metadata['EXTRA']['VIDEO']))
1068 {
1069 return $metadata;
1070 }
1071 }
1072
1073 return false;
1074 }
1075
1083 public static function getInnerFrameUrl($id, $provider = '')
1084 {
1085 $result = false;
1086
1087 $componentPath = \CComponentEngine::makeComponentPath('bitrix:main.urlpreview');
1088 if (!empty($componentPath))
1089 {
1090 $componentPath = getLocalPath('components'.$componentPath.'/frame.php');
1091 $uri = new Uri($componentPath);
1092 $uri->addParams(array('id' => $id, 'provider' => $provider));
1093 $result = static::normalizeUrl($uri->getLocator());
1094 }
1095
1096 return $result;
1097 }
1098}
static includeModule($moduleName)
Definition loader.php:69
static dispatch(Uri $uri)
Definition router.php:84
static getImAttach($url, $checkAccess=true, $userId=0)
static getRemoteUrlMetadata(Uri $uri)
static fetchImageMetadata(string $imageUrl, array &$metadata)
static getDynamicPreview($url, $checkAccess=true, $userId=0)
static refreshMetadata(array &$metadata)
static saveImage(string $tempPath, ?string $fileName)
static getUrlInfoFromExternal($url, $method, $checkAccess=true, $userId=0)
static downloadFile(string $url, ?string &$fileName=null, ?int $range=null)
static getMetadataByIds(array $ids)
static getMetadataByUrl($url, $addIfNew=true, $reuseExistingMetadata=true)
static getMetadataAndHtmlByUrl($url, $addIfNew=true, $reuseExistingMetadata=true)
static getImRich($url, $checkAccess=true, $userId=0)
static showView($userField, $userFieldParams, &$cacheTag, $edit=false)
static checkDynamicPreviewAccess($url, $userId=0)
static getTempPath(string $fileName)
static isIpAddressPrivate($ipAddress)
static getFileMetadata(HttpClient $client)
static getMetadataAndHtmlByIds(array $ids, $checkAccess=true, $userId=0)
static showEdit($userField, $userFieldParams)
static resolveTemporaryMetadata($id, $checkAccess=true, $userId=0)
static setMetadataImage($id, $imageUrl)
static getInnerFrameUrl($id, $provider='')
static validateRemoteMetadata(array $metadata)
static isImage($mime)
Definition mimetype.php:269
$GLOBALS['____1444769544']
Definition license.php:1