Created
February 19, 2025 13:06
-
-
Save EscApp2/d6846a5bbe204e5a1af759c8301b56f5 to your computer and use it in GitHub Desktop.
CIBlockPropertyCustomVideoHostingProp.php video vk dzen rutube
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <? | |
| define('STOP_STATISTICS', true); // otklyuchaem moduly veb-analitiki | |
| define("NO_KEEP_STATISTIC", true); // otklyuchaem moduly veb-analitiki | |
| define("NO_AGENT_CHECK", true); // otklyuchaem obrabotku agentov | |
| define("DisableEventsCheck", true); // zapret na otpravku neotpravlennih pochtovih soobshteniy iz BD https://dev.1c-bitrix.ru/api_help/main/general/mailevents.php | |
| define("BX_COMPRESSION_DISABLED", true); | |
| require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); | |
| // need https://gist.github.com/EscApp2/c7ab584e3488dfe3d145a464197350e7 | |
| class __ParseEmbedVideoHelper | |
| { | |
| public static function is_url($url) | |
| { | |
| return (bool)preg_match(" | |
| /^ # Start at the beginning of the text | |
| (?:ftp|https?|feed):\/\/ # Look for ftp, http, https or feed schemes | |
| (?: # Userinfo (optional) which is typically | |
| (?:(?:[\w\.\-\+!$&'\(\)*\+,;=]|%[0-9a-f]{2})+:)* # a username or a username and password | |
| (?:[\w\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})+@ # combination | |
| )? | |
| (?: | |
| (?:[a-z0-9\-\.]|%[0-9a-f]{2})+ # A domain name or a IPv4 address | |
| |(?:\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\]) # or a well formed IPv6 address | |
| ) | |
| (?::[0-9]+)? # Server port number (optional) | |
| (?:[\/|\?] | |
| (?:[\w#!:\.\?\+=&@$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2}) # The path and query (optional) | |
| *)? | |
| $/xi", $url); | |
| } | |
| public static function is_html($string) | |
| { | |
| $string = html_entity_decode($string); | |
| //https://stackoverflow.com/a/18242528 | |
| return preg_match("/<[^<]+>/", $string, $m) != 0; | |
| } | |
| public static function get_links_in_html($html) | |
| { | |
| $html = html_entity_decode($html); | |
| $pattern = "/(?:src|href)[\s]*=[\s]*(?:\"|')([\S]*)(?:\"|')/"; | |
| preg_match($pattern, $html, $matches); | |
| return $matches[1]; | |
| } | |
| public static function get_slugs($path) | |
| { | |
| $arPath = explode("/", $path); | |
| $arPath = array_filter($arPath); | |
| //$arPath = array_values($arPath); | |
| return $arPath; | |
| } | |
| public static function findUrlInText($text) | |
| { | |
| //https://stackoverflow.com/a/41242257 | |
| $regex = "/\b" . | |
| #Word cannot begin with special characters | |
| "(?<![@.,%&#-])" . | |
| #Protocols are optional, but take them with us if they are present | |
| "(?<protocol>\w{2,10}:\/\/)?" . | |
| #Domains have to be of a length of 1 chars or greater | |
| "((?:\w|\&\#\d{1,5};)[.-]?)+" . | |
| #The domain ending has to be between 2 to 15 characters | |
| "(\.([a-z]{2,15})" . | |
| #If no domain ending we want a port, only if a protocol is specified | |
| "|(?(protocol)(?:\:\d{1,6})|(?!)))" . | |
| "\b" . | |
| #Word cannot end with @ (made to catch emails) | |
| "(?![@])" . | |
| #We accept any number of slugs, given we have a char after the slash | |
| "(\/)?" . | |
| #If we have endings like ?=fds include the ending | |
| "(?:([\w\d\?\-=#:%@&.;])+(?:\/(?:([\w\d\?\-=#:%@&;.])+))*)?" . | |
| #The last char cannot be one of these symbols .,?!,- exclude these | |
| "(?<![.,?!-])/"; | |
| $matches = array(); | |
| preg_match_all($regex, $text, $matches); | |
| $arUrl = array(); | |
| if (count($matches[0]) > 0) { | |
| $arUrl = $matches[0]; | |
| } | |
| return $arUrl; | |
| } | |
| public function getData() | |
| { | |
| return $this->DATA; | |
| } | |
| } | |
| class __YoutubeVideoForPropHandler extends __ParseEmbedVideoHelper | |
| { | |
| public $DATA = array(); | |
| public function __construct($some) | |
| { | |
| if (self::is_html($some)) { | |
| $url = self::get_links_in_html($some); | |
| if (self::is_url($url) && self::is_domain($url)) { | |
| $id = self::get_id_from_url($url); | |
| } | |
| $embed_html = $some; | |
| } elseif (self::is_url($some) && self::is_domain($some)) { | |
| $url = $some; | |
| $id = self::get_id_from_url($url); | |
| } | |
| if ($id) { | |
| $this->DATA['id'] = $id; | |
| $this->DATA['content_url'] = $this->getContentUrl($id); | |
| $this->DATA['embed_url'] = $this->getEmbedUrl($id); | |
| $this->DATA['embed_html'] = '<iframe style="width: 100%;" src="' . $this->DATA['embed_url'] . '" | |
| frameborder="0" | |
| allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" | |
| referrerpolicy="strict-origin-when-cross-origin" | |
| allowfullscreen></iframe>'; | |
| $this->DATA['thumbnail_url'] = $this->getThumbnailUrl($id); | |
| $arResult = $this->getDataByRequest(); | |
| $this->DATA['duration'] = $arResult['DURATION']; //TODO seconds | |
| $this->DATA['title'] = $arResult['TITLE']; | |
| } | |
| } | |
| public static function isServiceUrl($url) | |
| { | |
| return self::is_domain($url); | |
| } | |
| public static function is_domain($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arAvailHost = array( | |
| "youtube.com", | |
| "www.youtube.com", | |
| "youtu.be" | |
| ); | |
| if (in_array($arUrl['host'], $arAvailHost)) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| public static function get_id_from_url($url) | |
| { | |
| $youtube_id = false; | |
| if (filter_var($url, FILTER_VALIDATE_URL) === false) { | |
| $youtube_id = $url; | |
| } else { | |
| preg_match('/[\\?\\&]v=([^\\?\\&]+)/', $url, $matches); | |
| if (empty($matches)) { | |
| $ar_url = parse_url($url); | |
| if ($ar_url['host'] == "youtu.be") { | |
| $matches[1] = str_replace("/", "", $ar_url['path']); | |
| $youtube_id = $matches[1]; | |
| } else { | |
| if (stripos($ar_url['path'], 'embed') !== false) { | |
| $arUrl = array_values(array_filter(explode("/", $ar_url['path']))); | |
| $youtube_id = $arUrl[1]; | |
| } | |
| } | |
| } else { | |
| $youtube_id = $matches[1]; | |
| } | |
| } | |
| return $youtube_id; | |
| } | |
| public static function getContentUrl($code) | |
| { | |
| return "https://www.youtube.com/watch?v=" . $code; | |
| } | |
| public static function getEmbedUrl($code) | |
| { | |
| return "https://www.youtube.com/embed/" . $code; | |
| } | |
| public static function getThumbnailUrl($code) | |
| { | |
| //https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api | |
| if ($code) { | |
| //return "https://img.youtube.com/vi/" . $code . "/default.jpg"; | |
| return "https://img.youtube.com/vi/" . $code . "/maxresdefault.jpg"; | |
| } | |
| return false; | |
| } | |
| private function getDataByRequest() | |
| { | |
| $URL = $this->DATA['content_url']; | |
| $arReturn = array(); | |
| //maybe video | |
| $opts = array( | |
| 'http' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ), | |
| 'https' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ) | |
| ); | |
| $context = stream_context_create($opts); | |
| $body = file_get_contents($URL, false, $context); | |
| $doc = new DOMDocument(); | |
| @$doc->loadHTML($body); | |
| $xpath = new DOMXpath($doc); | |
| $arRes = $xpath->query('//*[@property="og:title"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['TITLE'] = $element->getAttribute('content'); | |
| } | |
| $arRes = $xpath->query('//*[@itemprop="duration"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['DURATION'] = $element->getAttribute('content'); | |
| } | |
| //datePublished | |
| //uploadDate | |
| return $arReturn; | |
| } | |
| } | |
| if (!function_exists('http_build_url')) { | |
| // Define constants | |
| define('HTTP_URL_REPLACE', 0x0001); // Replace every part of the first URL when there's one of the second URL | |
| define('HTTP_URL_JOIN_PATH', 0x0002); // Join relative paths | |
| define('HTTP_URL_JOIN_QUERY', 0x0004); // Join query strings | |
| define('HTTP_URL_STRIP_USER', 0x0008); // Strip any user authentication information | |
| define('HTTP_URL_STRIP_PASS', 0x0010); // Strip any password authentication information | |
| define('HTTP_URL_STRIP_PORT', 0x0020); // Strip explicit port numbers | |
| define('HTTP_URL_STRIP_PATH', 0x0040); // Strip complete path | |
| define('HTTP_URL_STRIP_QUERY', 0x0080); // Strip query string | |
| define('HTTP_URL_STRIP_FRAGMENT', 0x0100); // Strip any fragments (#identifier) | |
| // Combination constants | |
| define('HTTP_URL_STRIP_AUTH', HTTP_URL_STRIP_USER | HTTP_URL_STRIP_PASS); | |
| define('HTTP_URL_STRIP_ALL', | |
| HTTP_URL_STRIP_AUTH | HTTP_URL_STRIP_PORT | HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT); | |
| /** | |
| * HTTP Build URL | |
| * Combines arrays in the form of parse_url() into a new string based on specific options | |
| * @name http_build_url | |
| * @param string|array $url The existing URL as a string or result from parse_url | |
| * @param string|array $parts Same as $url | |
| * @param int $flags URLs are combined based on these | |
| * @param array &$new_url If set, filled with array version of new url | |
| * @return string | |
| */ | |
| function http_build_url(/*string|array*/ $url, /*string|array*/ $parts = array(), /*int*/ $flags = HTTP_URL_REPLACE, | |
| /*array*/ &$new_url = false | |
| ) { | |
| // If the $url is a string | |
| if (is_string($url)) { | |
| $url = parse_url($url); | |
| } | |
| // If the $parts is a string | |
| if (is_string($parts)) { | |
| $parts = parse_url($parts); | |
| } | |
| // Scheme and Host are always replaced | |
| if (isset($parts['scheme'])) { | |
| $url['scheme'] = $parts['scheme']; | |
| } | |
| if (isset($parts['host'])) { | |
| $url['host'] = $parts['host']; | |
| } | |
| // (If applicable) Replace the original URL with it's new parts | |
| if (HTTP_URL_REPLACE & $flags) { | |
| // Go through each possible key | |
| foreach (array('user', 'pass', 'port', 'path', 'query', 'fragment') as $key) { | |
| // If it's set in $parts, replace it in $url | |
| if (isset($parts[$key])) { | |
| $url[$key] = $parts[$key]; | |
| } | |
| } | |
| } else { | |
| // Join the original URL path with the new path | |
| if (isset($parts['path']) && (HTTP_URL_JOIN_PATH & $flags)) { | |
| if (isset($url['path']) && $url['path'] != '') { | |
| // If the URL doesn't start with a slash, we need to merge | |
| if ($url['path'][0] != '/') { | |
| // If the path ends with a slash, store as is | |
| if ('/' == $parts['path'][strlen($parts['path']) - 1]) { | |
| $sBasePath = $parts['path']; | |
| } // Else trim off the file | |
| else { | |
| // Get just the base directory | |
| $sBasePath = dirname($parts['path']); | |
| } | |
| // If it's empty | |
| if ('' == $sBasePath) { | |
| $sBasePath = '/'; | |
| } | |
| // Add the two together | |
| $url['path'] = $sBasePath . $url['path']; | |
| // Free memory | |
| unset($sBasePath); | |
| } | |
| if (false !== strpos($url['path'], './')) { | |
| // Remove any '../' and their directories | |
| while (preg_match('/\w+\/\.\.\//', $url['path'])) { | |
| $url['path'] = preg_replace('/\w+\/\.\.\//', '', $url['path']); | |
| } | |
| // Remove any './' | |
| $url['path'] = str_replace('./', '', $url['path']); | |
| } | |
| } else { | |
| $url['path'] = $parts['path']; | |
| } | |
| } | |
| // Join the original query string with the new query string | |
| if (isset($parts['query']) && (HTTP_URL_JOIN_QUERY & $flags)) { | |
| if (isset($url['query'])) { | |
| $url['query'] .= '&' . $parts['query']; | |
| } else { | |
| $url['query'] = $parts['query']; | |
| } | |
| } | |
| } | |
| // Strips all the applicable sections of the URL | |
| if (HTTP_URL_STRIP_USER & $flags) { | |
| unset($url['user']); | |
| } | |
| if (HTTP_URL_STRIP_PASS & $flags) { | |
| unset($url['pass']); | |
| } | |
| if (HTTP_URL_STRIP_PORT & $flags) { | |
| unset($url['port']); | |
| } | |
| if (HTTP_URL_STRIP_PATH & $flags) { | |
| unset($url['path']); | |
| } | |
| if (HTTP_URL_STRIP_QUERY & $flags) { | |
| unset($url['query']); | |
| } | |
| if (HTTP_URL_STRIP_FRAGMENT & $flags) { | |
| unset($url['fragment']); | |
| } | |
| // Store the new associative array in $new_url | |
| $new_url = $url; | |
| // Combine the new elements into a string and return it | |
| return | |
| ((isset($url['scheme'])) ? $url['scheme'] . '://' : '') | |
| . ((isset($url['user'])) ? $url['user'] . ((isset($url['pass'])) ? ':' . $url['pass'] : '') . '@' : '') | |
| . ((isset($url['host'])) ? $url['host'] : '') | |
| . ((isset($url['port'])) ? ':' . $url['port'] : '') | |
| . ((isset($url['path'])) ? $url['path'] : '') | |
| . ((isset($url['query'])) ? '?' . $url['query'] : '') | |
| . ((isset($url['fragment'])) ? '#' . $url['fragment'] : ''); | |
| } | |
| } | |
| class __VkVideoForPropHandler extends __ParseEmbedVideoHelper | |
| { | |
| public $DATA = array(); | |
| public function __construct($some) | |
| { | |
| if (self::is_html($some)) { | |
| $url = self::get_links_in_html($some); | |
| if (self::is_url($url) && self::is_domain($url)) { | |
| $id = self::get_id_from_url($url); | |
| } | |
| $embed_html = $some; | |
| } elseif (self::is_url($some) && self::is_domain($some)) { | |
| $url = $some; | |
| $id = self::get_id_from_url($url); | |
| } | |
| if ($id) { | |
| $this->DATA['id'] = $id; | |
| $this->DATA['content_url'] = $this->getContentUrl($id, $url); | |
| $this->DATA['embed_url'] = $this->getEmbedUrl($id, $url); | |
| $this->DATA['embed_html'] = '<iframe style="width: 100%;" src="' . $this->DATA['embed_url'] . '" | |
| frameborder="0" | |
| allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" | |
| referrerpolicy="strict-origin-when-cross-origin" | |
| allowfullscreen></iframe>'; | |
| $this->DATA['thumbnail_url'] = $this->getThumbnailUrl($id, $url); | |
| $arResult = $this->getDataByRequest(); | |
| $this->DATA['duration'] = $arResult['SEC_DURATION']; | |
| $this->DATA['title'] = $arResult['TITLE']; | |
| } | |
| } | |
| public static function isServiceUrl($url) | |
| { | |
| return self::is_domain($url); | |
| } | |
| public static function is_domain($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arAvailHost = array( | |
| "vk.com", | |
| "m.vk.com" | |
| ); | |
| if (in_array($arUrl['host'], $arAvailHost)) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| public static function get_id_from_url($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arQuery = array(); | |
| parse_str($arUrl['query'], $arQuery); | |
| $arSlugs = self::get_slugs($arUrl['path']); | |
| if ($arUrl['path'] == "/video_ext.php") { | |
| //embed | |
| $id = $arQuery['oid'] . "_" . $arQuery['id']; | |
| return $id; | |
| } elseif ($arSlugs[1] == "video" && !empty($arQuery['z'])) { | |
| $arZ = explode("/",$arQuery['z']); | |
| $id = str_replace("video", "", $arZ[0]); | |
| return $id; | |
| } elseif (strpos($arUrl['path'], '/video-') !== false) { | |
| $id = str_replace("/video", "", $arUrl['path']); | |
| return $id; | |
| } | |
| return false; | |
| } | |
| public static function getContentUrl($id, $url) | |
| { | |
| return "https://vk.com/video" . $id; | |
| } | |
| public static function getEmbedUrl($id, $url) | |
| { | |
| return self::getVkVideoIframe($url); | |
| } | |
| public function getThumbnailUrl($id, $url) | |
| { | |
| $URL = $this->DATA['embed_url']; | |
| return self::getVkVideoThumbnail($URL); | |
| } | |
| public static function getVkVideoIframe($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arQuery = array(); | |
| parse_str($arUrl['query'], $arQuery); | |
| $arSlugs = self::get_slugs($arUrl['path']); | |
| if ($arUrl['path'] == "/video_ext.php") { | |
| return $url; | |
| //embed | |
| //return $url."&autoplay=1"; | |
| //$ob_uri = new \Bitrix\Main\Web\Uri($url); | |
| //$ob_uri->addParams(array('autoplay' => 1)); | |
| //return $ob_uri->getUri(); | |
| } elseif ($arSlugs[1] == "video" && !empty($arQuery['z'])) { | |
| $arZ = explode("/",$arQuery['z']); | |
| $new_url = "https://vk.com/".$arZ[0]; | |
| return self::getVkVideoIframe($new_url); | |
| } elseif (strpos($arUrl['path'], '/video-') !== false) { | |
| //maybe video | |
| $opts = array( | |
| 'http' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ) | |
| ); | |
| $context = stream_context_create($opts); | |
| $body = file_get_contents($url, false, $context); | |
| $doc = new DOMDocument(); | |
| @$doc->loadHTML($body); | |
| $xpath = new DOMXpath($doc); | |
| $arRes = $xpath->query('//*[@itemprop="embedUrl"]'); | |
| foreach ($arRes as $element) { | |
| $href = $element->getAttribute('href'); | |
| return $href; | |
| //$ob_uri = new \Bitrix\Main\Web\Uri($href); | |
| //$ob_uri->addParams(array('autoplay' => 1)); | |
| //return $ob_uri->getUri(); | |
| } | |
| } | |
| return false; | |
| } | |
| public static function getVkVideoThumbnail($url) | |
| { | |
| $arUrl = parse_url($url); | |
| if ($arUrl['host'] == "vk.com") { | |
| $picture_url = false; | |
| if ($arUrl['path'] == "/video_ext.php") { | |
| //embed | |
| $opts = array( | |
| 'http' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ) | |
| ); | |
| $context = stream_context_create($opts); | |
| $body = file_get_contents($url, false, $context); | |
| $matches = array(); | |
| //https://stackoverflow.com/questions/18093990/php-regex-to-get-all-image-urls-on-the-page | |
| /*preg_match_all('/https?:\/\/[^\/\s]+\/\S+.(jpe?g|png|gif|tif|exf|svg|wfm|webp)/', $body, $matches, | |
| PREG_SET_ORDER); | |
| if (count($matches) > 0) { | |
| $picture_url = $matches[0][0]; | |
| } else {*/ | |
| preg_match_all('/background-image:url\(([^\)]+)\)/', $body, $matches, PREG_SET_ORDER); | |
| if (count($matches) > 0) { | |
| $picture_url = $matches[0][1]; | |
| } | |
| //} | |
| } elseif (strpos($arUrl['path'], '/video-') !== false) { | |
| //maybe video | |
| $body = file_get_contents($url); | |
| $doc = new DOMDocument(); | |
| @$doc->loadHTML($body); | |
| $xpath = new DOMXpath($doc); | |
| //https://github.com/dpb587/microdata-dom.php/blob/master/src/MicrodataDOM/DOMDocument.php | |
| $arRes = $xpath->query('//*[@itemprop="thumbnailUrl"]'); | |
| //https://i.mycdn.me/getVideoPreview?id=4793677842954&idx=3&type=39&tkn=TX_vEVYDI5o3Jqs5lZJvGuObbd8&fn=vid_xl | |
| foreach ($arRes as $element) { | |
| $picture_url = $element->getAttribute('href'); | |
| break; | |
| } | |
| } | |
| if ($picture_url) { | |
| $arPictureUrl = parse_url($picture_url); | |
| $arQuery = array(); | |
| parse_str($arPictureUrl['query'], $arQuery); | |
| unset($arQuery['fn']); | |
| //$arQuery['fn'] = "vid_h"; | |
| $arPictureUrl['query'] = http_build_query($arQuery); | |
| $picture_url = http_build_url($arPictureUrl); | |
| } | |
| return $picture_url; | |
| } | |
| return false; | |
| } | |
| private function getDataByRequest() | |
| { | |
| $URL = $this->DATA['content_url']; | |
| $arReturn = array(); | |
| //maybe video | |
| $opts = array( | |
| 'http' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ), | |
| 'https' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ) | |
| ); | |
| $context = stream_context_create($opts); | |
| $body = file_get_contents($URL, false, $context); | |
| $doc = new DOMDocument(); | |
| @$doc->loadHTML($body); | |
| $xpath = new DOMXpath($doc); | |
| $arRes = $xpath->query('//*[@itemprop="thumbnailUrl"]'); | |
| foreach ($arRes as $element) { | |
| $picture_url = $element->getAttribute('href'); | |
| if ($picture_url) { | |
| $arPictureUrl = parse_url($picture_url); | |
| $arQuery = array(); | |
| parse_str($arPictureUrl['query'], $arQuery); | |
| unset($arQuery['fn']); | |
| //$arQuery['fn'] = "vid_h"; | |
| $arPictureUrl['query'] = http_build_query($arQuery); | |
| $picture_url = http_build_url($arPictureUrl); | |
| } | |
| $arReturn['THUMBNAIL'] = $picture_url; | |
| } | |
| $arRes = $xpath->query('//*[@itemprop="name"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['TITLE'] = $element->getAttribute('content'); | |
| } | |
| $arRes = $xpath->query('//*[@itemprop="duration"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['DURATION'] = $element->getAttribute('content'); | |
| } | |
| $arRes = $xpath->query('//*[@property="video:duration"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['SEC_DURATION'] = $element->getAttribute('content'); | |
| } | |
| return $arReturn; | |
| } | |
| } | |
| class __DzenVideoForPropHandler extends __ParseEmbedVideoHelper | |
| { | |
| public $DATA = array(); | |
| public function __construct($some) | |
| { | |
| if (self::is_html($some)) { | |
| $url = self::get_links_in_html($some); | |
| if (self::is_url($url) && self::is_domain($url)) { | |
| $id = self::get_id_from_url($url); | |
| } | |
| $embed_html = $some; | |
| } elseif (self::is_url($some) && self::is_domain($some)) { | |
| $url = $some; | |
| $id = self::get_id_from_url($url); | |
| } | |
| if ($id) { | |
| $this->DATA['id'] = $id; | |
| $this->DATA['content_url'] = $this->getContentUrl($id, $url); | |
| $this->DATA['embed_url'] = $this->getEmbedUrl($id, $url); | |
| $this->DATA['embed_html'] = '<iframe style="width: 100%;" src="' . $this->DATA['embed_url'] . '" | |
| allow="autoplay; fullscreen; accelerometer; gyroscope; picture-in-picture; encrypted-media" | |
| frameborder="0" scrolling="no" | |
| allowfullscreen></iframe>'; | |
| $arResult = $this->getDataByRequest(); | |
| // TODO from seconds to schema | |
| $this->DATA['duration'] = $arResult['DURATION']; | |
| $this->DATA['title'] = $arResult['TITLE']; | |
| $this->DATA['thumbnail_url'] = $arResult['THUMBNAIL']; | |
| } | |
| } | |
| public static function isServiceUrl($url) | |
| { | |
| //https://dzen.ru/embed/vLhLO6FY9FFk //ok | |
| //https://dzen.ru/video/watch/648f39ee8db8a360149bd693?preview //not ok | |
| $ok = false; | |
| if(self::is_domain($url)){ | |
| $arUrl = parse_url($url); | |
| $arSlugs = self::get_slugs($arUrl['path']); | |
| if($arSlugs[1] == "embed"){ | |
| $ok = true; | |
| } | |
| } | |
| return $ok; | |
| } | |
| public static function is_domain($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arAvailHost = array( | |
| "dzen.ru", | |
| ); | |
| if (in_array($arUrl['host'], $arAvailHost)) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| public static function get_id_from_url($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arSlugs = self::get_slugs($arUrl['path']); | |
| return $arSlugs[2]; | |
| } | |
| public static function getContentUrl($id, $url) | |
| { | |
| return ""; | |
| } | |
| public static function getEmbedUrl($id, $url) | |
| { | |
| return "https://dzen.ru/embed/".$id; | |
| } | |
| private function getDataByRequest() | |
| { | |
| $URL = $this->DATA['embed_url']; | |
| $arReturn = array(); | |
| //maybe video | |
| $opts = array( | |
| 'http' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ), | |
| 'https' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ) | |
| ); | |
| $context = stream_context_create($opts); | |
| $body = file_get_contents($URL, false, $context); | |
| $doc = new DOMDocument(); | |
| @$doc->loadHTML($body); | |
| $xpath = new DOMXpath($doc); | |
| $arRes = $xpath->query('//*[@property="og:title"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['TITLE'] = $element->getAttribute('content'); | |
| } | |
| $arRes = $xpath->query('//*[@property="duration"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['DURATION'] = $element->getAttribute('content'); | |
| } | |
| $arRes = $xpath->query('//*[@property="og:image:secure_url"]'); | |
| foreach ($arRes as $element) { | |
| $arReturn['THUMBNAIL'] = $element->getAttribute('content'); | |
| } | |
| //ya:ovs:upload_date | |
| return $arReturn; | |
| } | |
| } | |
| class __RutubeVideoForPropHandler extends __ParseEmbedVideoHelper{ | |
| public $DATA = array(); | |
| public function __construct($some) | |
| { | |
| if (self::is_html($some)) { | |
| $url = self::get_links_in_html($some); | |
| if (self::is_url($url) && self::is_domain($url)) { | |
| $id = self::get_id_from_url($url); | |
| } | |
| $embed_html = $some; | |
| } elseif (self::is_url($some) && self::is_domain($some)) { | |
| $url = $some; | |
| $id = self::get_id_from_url($url); | |
| } | |
| if ($id) { | |
| $this->DATA['id'] = $id; | |
| $this->DATA['content_url'] = $this->getContentUrl($id, $url); | |
| $this->DATA['embed_url'] = $this->getEmbedUrl($id, $url); | |
| $this->DATA['embed_html'] = '<iframe style="width: 100%;" src="' . $this->DATA['embed_url'] . '" | |
| allow="clipboard-write; autoplay" | |
| frameBorder="0" | |
| webkitAllowFullScreen | |
| mozallowfullscreen | |
| allowfullscreen></iframe>'; | |
| $arResult = $this->getDataByRequest(); | |
| $this->DATA['duration'] = $arResult['DURATION']; | |
| $this->DATA['title'] = $arResult['TITLE']; | |
| $this->DATA['thumbnail_url'] = $arResult['THUMBNAIL']; | |
| } | |
| } | |
| public static function isServiceUrl($url) | |
| { | |
| return self::is_domain($url); | |
| } | |
| public static function is_domain($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arAvailHost = array( | |
| "rutube.ru", | |
| ); | |
| if (in_array($arUrl['host'], $arAvailHost)) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| public static function get_id_from_url($url) | |
| { | |
| $arUrl = parse_url($url); | |
| $arSlugs = self::get_slugs($arUrl['path']); | |
| $id = array_pop($arSlugs); | |
| return $id; | |
| } | |
| public static function getContentUrl($id, $url) | |
| { | |
| return "https://rutube.ru/video/".$id."/"; | |
| } | |
| public static function getEmbedUrl($id, $url) | |
| { | |
| return "https://rutube.ru/play/embed/".$id; | |
| } | |
| private function getDataByRequest() | |
| { | |
| //https://github.com/suth/video-thumbnails/blob/master/php/providers/class-rutube-thumbnails.php | |
| $id = $this->DATA['id']; | |
| if ( strlen( $id ) < 32 ) { | |
| $URL = "http://rutube.ru/api/oembed/?url=http%3A//rutube.ru/tracks/$id.html&format=json"; | |
| } else { | |
| $URL = "http://rutube.ru/api/video/$id/?format=json"; | |
| } | |
| $arReturn = array(); | |
| //maybe video | |
| $opts = array( | |
| 'http' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ), | |
| 'https' => | |
| array( | |
| 'user_agent' => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36", | |
| ) | |
| ); | |
| $context = stream_context_create($opts); | |
| $body = file_get_contents($URL, false, $context); | |
| if($body){ | |
| $json = json_decode($body ,true); | |
| $arReturn['THUMBNAIL'] = $json['thumbnail_url']; | |
| $arReturn['DURATION'] = $json['duration']; | |
| $arReturn['TITLE'] = $json['title']; | |
| } | |
| return $arReturn; | |
| } | |
| } | |
| class __WorkWithVideoForProp extends __ParseEmbedVideoHelper | |
| { | |
| public static function getEmbedData($some) | |
| { | |
| if (self::is_html($some)) { | |
| $url = self::get_links_in_html($some); | |
| $arUrl = self::findUrlInText($some); | |
| $url = $arUrl[0]; | |
| } elseif (self::is_url($some)) { | |
| $url = $some; | |
| } | |
| if ($url) { | |
| $class = self::getHandler($url); | |
| if ($class) { | |
| return $class->getData(); | |
| } | |
| } | |
| return false; | |
| } | |
| public static function getHandler($url) | |
| { | |
| $arClassList = array( | |
| "__VkVideoForPropHandler", | |
| "__YoutubeVideoForPropHandler", | |
| "__DzenVideoForPropHandler", | |
| "__RutubeVideoForPropHandler", | |
| ); | |
| foreach ($arClassList as $class_name) { | |
| if ($class_name::isServiceUrl($url)) { | |
| return new $class_name($url); | |
| } | |
| } | |
| return false; | |
| } | |
| } | |
| $action = (string)$_REQUEST['action']; | |
| function sendJsonAnswer($result) | |
| { | |
| global $APPLICATION; | |
| $APPLICATION->RestartBuffer(); | |
| header('Content-Type: application/json'); | |
| echo \Bitrix\Main\Web\Json::encode($result); | |
| CMain::FinalActions(); | |
| die(); | |
| } | |
| function getExtension($filePath) | |
| { | |
| $ar = explode('.', $filePath); | |
| return array_pop($ar); | |
| } | |
| if(!function_exists('getImageData')){ | |
| function getImageData($path){ | |
| if(is_file($path) && is_readable($path)){ | |
| $ImageData = array(); | |
| if(function_exists('getimagesize')){ | |
| $size = getimagesize($path); | |
| $ImageData['width'] = $size[0]; | |
| $ImageData['height'] = $size[1]; | |
| $ImageData['mime_type'] = image_type_to_mime_type($size[2]); | |
| $ImageData['extension'] = image_type_to_extension($size[2], false); | |
| }elseif(class_exists('Imagick')){ | |
| $res_im = new imagick($path); | |
| $geo = $res_im->getImageGeometry(); | |
| $ImageData['width'] = $geo['width']; | |
| $ImageData['height'] = $geo['height']; | |
| $ImageData['file_size'] = $res_im->getImageLength(); | |
| $ImageData['mime_type'] = $res_im->getImageMimeType(); | |
| }elseif(function_exists('finfo_open')){ | |
| $buffer = file_get_contents($path); | |
| $f = finfo_open(); | |
| $ImageData[0] = finfo_buffer($f, $buffer); | |
| $ImageData['mime_type'] = finfo_buffer($f, $buffer,FILEINFO_MIME_TYPE); | |
| finfo_close($f); | |
| } | |
| if(empty($ImageData['file_size'])){ | |
| $ImageData['file_size'] = filesize($path); | |
| } | |
| return $ImageData; | |
| } | |
| return false; | |
| } | |
| } | |
| if (!function_exists('getimagesizefromstring')) { | |
| function getimagesizefromstring($data, &$imageinfo = array()) | |
| { | |
| $uri = 'data://application/octet-stream;base64,' . base64_encode($data); | |
| return getimagesize($uri, $imageinfo); | |
| } | |
| } | |
| if($action == "get_data_by_url"){ | |
| $url = (string)$_REQUEST['url']; | |
| $arResult = array( | |
| 'STATUS'=>"ERROR", | |
| ); | |
| if($url){ | |
| $arDATA = __WorkWithVideoForProp::getEmbedData($url); | |
| if($arDATA) { | |
| //$arDATA['thumbnail_file_content'] = base64_encode(file_get_contents($arDATA['thumbnail_url'])); | |
| //$arDATA['thumbnail_file_name'] = $arDATA['id'].".".getExtension($arDATA['thumbnail_url']); | |
| if($arDATA['thumbnail_url']){ | |
| $arDATA['thumbnail'] = CFile::MakeFileArray($arDATA['thumbnail_url']); | |
| $content = file_get_contents($arDATA['thumbnail_url']); | |
| $size = getimagesizefromstring($content); | |
| if ($size) { | |
| $arDATA['thumbnail']['width'] = $size[0]; | |
| $arDATA['thumbnail']['height'] = $size[1]; | |
| } | |
| } | |
| $arResult = array( | |
| 'STATUS' => "OK", | |
| 'DATA' => $arDATA, | |
| ); | |
| }else{ | |
| $arResult['MESSAGE'] = "Данная ссылка не поддерживается"; | |
| } | |
| } | |
| sendJsonAnswer($arResult); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| use \Bitrix\Main\Localization\Loc; | |
| class CIBlockPropertyCustomVideoHostingProp | |
| { | |
| private static $showedCss = false; | |
| private static $showedJs = false; | |
| static public function GetUserTypeDescription() | |
| { | |
| return array( | |
| 'PROPERTY_TYPE' => 'S', | |
| 'USER_TYPE' => 'CustomVideoHosting', | |
| 'DESCRIPTION' => "Видеохостинги", | |
| 'GetPropertyFieldHtml' => array(__CLASS__, 'GetPropertyFieldHtml'), | |
| 'ConvertToDB' => array(__CLASS__, 'ConvertToDB'), | |
| 'ConvertFromDB' => array(__CLASS__, 'ConvertFromDB'), | |
| 'GetSettingsHTML' => array(__CLASS__, 'GetSettingsHTML'), | |
| //'PrepareSettings' => array(__CLASS__, 'PrepareUserSettings'), | |
| 'GetLength' => array(__CLASS__, 'GetLength'), //need test | |
| 'GetPublicViewHTML' => array(__CLASS__, 'GetPublicViewHTML') | |
| ); | |
| } | |
| public static function GetPropertyFieldHtml($arProperty, $value, $strHTMLControlName) | |
| { | |
| $hideText = "Свернуть"; | |
| $clearText = "Удалить"; | |
| $UpdateText = "Изменить"; | |
| $SeeText = "Посмотреть результат"; | |
| self::showCss(); | |
| self::showJs(); | |
| //pre($arProperty); | |
| //pre($value); | |
| /**/ | |
| $result = ''; | |
| /* | |
| if(!empty($arProperty['USER_TYPE_SETTINGS'])){ | |
| $arFields = self::prepareSetting($arProperty['USER_TYPE_SETTINGS']); | |
| } | |
| else{ | |
| return '<span>'.Loc::getMessage('IEX_CPROP_ERROR_INCORRECT_SETTINGS').'</span>'; | |
| }*/ | |
| $result .= '<div class="mf-gray"><a class="cl vh-toggle">'.$hideText.'</a>'; | |
| //if($arProperty['MULTIPLE'] === 'Y'){ | |
| $result .= ' | <a class="cl vh-delete">'.$clearText.'</a>'; | |
| //} | |
| $result .= '</div>'; | |
| $addClass = ""; | |
| $tabText = ""; | |
| $v = !empty($value['VALUE']["INPUT_VALUE"]) ? $value['VALUE']["INPUT_VALUE"] : ''; | |
| if($v){ | |
| $addClass = "one-tab"; | |
| $tabText = $UpdateText; | |
| } | |
| $result .= '<table class="mf-fields-list active js_custom_video_hosting '.$addClass.' ">'; | |
| /* | |
| foreach ($arFields as $code => $arItem){ | |
| if($arItem['TYPE'] === 'string'){ | |
| $result .= self::showString($code, $arItem['TITLE'], $value, $strHTMLControlName); | |
| } | |
| else if($arItem['TYPE'] === 'file'){ | |
| $result .= self::showFile($code, $arItem['TITLE'], $value, $strHTMLControlName); | |
| } | |
| else if($arItem['TYPE'] === 'text'){ | |
| $result .= self::showTextarea($code, $arItem['TITLE'], $value, $strHTMLControlName); | |
| } | |
| else if($arItem['TYPE'] === 'date'){ | |
| $result .= self::showDate($code, $arItem['TITLE'], $value, $strHTMLControlName); | |
| } | |
| else if($arItem['TYPE'] === 'element'){ | |
| $result .= self::showBindElement($code, $arItem['TITLE'], $value, $strHTMLControlName); | |
| } | |
| } | |
| */ | |
| $result .= '<tr> | |
| <td align="right" valign="top" colspan="2"> | |
| <div class="mf-gray" ><a class="cl vh-one-tab-toggle ">'.$tabText.'</a></div> | |
| </td> | |
| </tr>'; | |
| $code = "INPUT_VALUE"; | |
| $title = "Введите встраиваемый текст или ссылку"; | |
| $v = !empty($value['VALUE'][$code]) ? $value['VALUE'][$code] : ''; | |
| $hash = self::javaStringHashCode($v); | |
| $result .= '<tr class="first-tab"> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><textarea rows="8" class="js_raw_input_value" data-hash="'.$hash.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']">'.$v.'</textarea></td> | |
| </tr>'; | |
| $code = "HEADER"; | |
| $title = "Заголовок видео"; | |
| $v = !empty($value['VALUE'][$code]) ? $value['VALUE'][$code] : ''; | |
| $result .= '<tr class="second-tab"> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><input type="text" value="'.$v.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| $code = "DIRECT_LINK"; | |
| $title = "Прямая ссылка"; | |
| $v = !empty($value['VALUE'][$code]) ? $value['VALUE'][$code] : ''; | |
| $result .= '<tr class="hidden-allways"> | |
| <td align="right">'.$title.': </td> | |
| <td><input type="text" value="'.$v.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| $code = "EMBED_LINK"; | |
| $title = "Встраиваемая ссылка"; | |
| $v = !empty($value['VALUE'][$code]) ? $value['VALUE'][$code] : ''; | |
| $result .= '<tr class="hidden-allways" > | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><input type="text" value="'.$v.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| $code = "PREVIEW_PIСTURE"; | |
| $title = "Изображение превью"; | |
| $result .= self::showFile($code, $title, $value, $strHTMLControlName, 'second-tab'); | |
| /* | |
| $result .= '<tr class="second-tab"> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><input type="text" value="'.$v.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| */ | |
| $code = "DURATION"; | |
| $title = "Длительность видео"; | |
| $v = !empty($value['VALUE'][$code]) ? $value['VALUE'][$code] : ''; | |
| $result .= '<tr class="hidden-allways" > | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><input type="text" value="'.$v.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| $code = "IFRAME_PREVIEW"; | |
| $title = "Встраивание превью"; | |
| $v = !empty($value['VALUE'][$code]) ? $value['VALUE'][$code] : ''; | |
| $result .= '<tr class="second-tab"> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><div class="js_video_hosting_preview">'.$v.'</div> | |
| <textarea style="display:none" name="'.$strHTMLControlName['VALUE'].'['.$code.']">'.$v.'</textarea> | |
| </td> | |
| </tr>'; | |
| /* | |
| $code = "AUTOPLAY"; | |
| $title = "Автоплей"; | |
| $result .= '<tr class="second-tab" > | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><input type="text" value="'.$v.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| */ | |
| $result .= '</table>'; | |
| return $result; | |
| } | |
| public static function GetPublicViewHTML($arProperty, $value, $strHTMLControlName) | |
| { | |
| if($value['VALUE']){ | |
| if(!empty($value['VALUE']['IFRAME_PREVIEW'])){ | |
| return $value['VALUE']['IFRAME_PREVIEW']; | |
| } | |
| } | |
| return ""; | |
| } | |
| public static function GetSettingsHTML($arProperty, $strHTMLControlName, &$arPropertyFields) | |
| { | |
| $btnAdd = Loc::getMessage('IEX_CPROP_SETTING_BTN_ADD'); | |
| $settingsTitle = Loc::getMessage('IEX_CPROP_SETTINGS_TITLE'); | |
| $arPropertyFields = array( | |
| //'USER_TYPE_SETTINGS_TITLE' => $settingsTitle, | |
| 'HIDE' => array('ROW_COUNT', 'COL_COUNT', 'DEFAULT_VALUE', 'SMART_FILTER', 'WITH_DESCRIPTION', 'FILTRABLE', 'MULTIPLE_CNT', 'IS_REQUIRED'), | |
| 'SET' => array( | |
| 'MULTIPLE_CNT' => 1, | |
| 'SMART_FILTER' => 'N', | |
| 'FILTRABLE' => 'N', | |
| 'SEARCHABLE' => 1 | |
| ), | |
| ); | |
| $result = ""; | |
| /* | |
| self::showJsForSetting($strHTMLControlName["NAME"]); | |
| self::showCssForSetting(); | |
| $result = '<tr><td colspan="2" align="center"> | |
| <table id="many-fields-table" class="many-fields-table internal"> | |
| <tr valign="top" class="heading mf-setting-title"> | |
| <td>XML_ID</td> | |
| <td>'.Loc::getMessage('IEX_CPROP_SETTING_FIELD_TITLE').'</td> | |
| <td>'.Loc::getMessage('IEX_CPROP_SETTING_FIELD_SORT').'</td> | |
| <td>'.Loc::getMessage('IEX_CPROP_SETTING_FIELD_TYPE').'</td> | |
| </tr>'; | |
| $arSetting = self::prepareSetting($arProperty['USER_TYPE_SETTINGS']); | |
| if(!empty($arSetting)){ | |
| foreach ($arSetting as $code => $arItem) { | |
| $result .= ' | |
| <tr valign="top"> | |
| <td><input type="text" class="inp-code" size="20" value="'.$code.'"></td> | |
| <td><input type="text" class="inp-title" size="35" name="'.$strHTMLControlName["NAME"].'['.$code.'_TITLE]" value="'.$arItem['TITLE'].'"></td> | |
| <td><input type="text" class="inp-sort" size="5" name="'.$strHTMLControlName["NAME"].'['.$code.'_SORT]" value="'.$arItem['SORT'].'"></td> | |
| <td> | |
| <select class="inp-type" name="'.$strHTMLControlName["NAME"].'['.$code.'_TYPE]"> | |
| '.self::getOptionList($arItem['TYPE']).' | |
| </select> | |
| </td> | |
| </tr>'; | |
| } | |
| } | |
| $result .= ' | |
| <tr valign="top"> | |
| <td><input type="text" class="inp-code" size="20"></td> | |
| <td><input type="text" class="inp-title" size="35"></td> | |
| <td><input type="text" class="inp-sort" size="5" value="500"></td> | |
| <td> | |
| <select class="inp-type"> '.self::getOptionList().'</select> | |
| </td> | |
| </tr> | |
| </table> | |
| <tr> | |
| <td colspan="2" style="text-align: center;"> | |
| <input type="button" value="'.$btnAdd.'" onclick="addNewRows()"> | |
| </td> | |
| </tr> | |
| </td></tr>'; | |
| */ | |
| return $result; | |
| } | |
| public static function PrepareUserSettings($arProperty) | |
| { | |
| $result = []; | |
| if(!empty($arProperty['USER_TYPE_SETTINGS'])){ | |
| foreach ($arProperty['USER_TYPE_SETTINGS'] as $code => $value) { | |
| $result[$code] = $value; | |
| } | |
| } | |
| return $result; | |
| } | |
| public static function GetLength($arProperty, $arValue) | |
| { | |
| //pre($arValue); die(); | |
| /* | |
| * $arProperty["IS_REQUIRED"] == "Y" | |
| && $arProperty['PROPERTY_TYPE'] != 'F' | |
| * */ | |
| $arFields = self::prepareSetting(unserialize($arProperty['USER_TYPE_SETTINGS'])); | |
| $result = false; | |
| foreach($arValue['VALUE'] as $code => $value){ | |
| if($arFields[$code]['TYPE'] === 'file'){ | |
| if(!empty($value['name']) || (!empty($value['OLD']) && empty($value['DEL']))){ | |
| $result = true; | |
| break; | |
| } | |
| } | |
| else{ | |
| if(!empty($value)){ | |
| $result = true; | |
| break; | |
| } | |
| } | |
| } | |
| return $result; | |
| } | |
| public static function ConvertToDB($arProperty, $arValue) | |
| { | |
| if($_REQUEST['PROP_del']) { | |
| if ($_REQUEST['PROP_del'][$arProperty['ID']]) { | |
| $arFilesCodes = array(); | |
| $arFields = self::prepareSetting($arProperty['USER_TYPE_SETTINGS']); | |
| foreach($arValue['VALUE'] as $code => $value){ | |
| if($arFields[$code]['TYPE'] === 'file'){ | |
| $arFilesCodes[] = $code; | |
| } | |
| } | |
| $arCurProps = array(); | |
| foreach($arValue['VALUE'] as $code => $arVal){ | |
| if(in_array($code,$arFilesCodes)){ | |
| if(is_array($arVal)){ | |
| if($arVal['OLD']){ | |
| $arCurProps[$code] = $arVal['OLD']; | |
| } | |
| } | |
| } | |
| } | |
| $SaveID = false; | |
| if($_REQUEST['PROP']) { | |
| if ($_REQUEST['PROP'][$arProperty['ID']]) { | |
| foreach($_REQUEST['PROP'][$arProperty['ID']] as $save_id=>$arVal){ | |
| foreach( $arVal['VALUE'] as $code => $arOneVal){ | |
| if(in_array($code,$arFilesCodes)){ | |
| if(is_array($arOneVal)){ | |
| if($arOneVal['OLD'] == $arCurProps[$code]){ | |
| $SaveID = $save_id; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if($SaveID){ | |
| $delVal = $_REQUEST['PROP_del'][$arProperty['ID']][$SaveID]; | |
| }else{ | |
| $delVal = array_values($_REQUEST['PROP_del'][$arProperty['ID']])[0]; | |
| } | |
| foreach($delVal['VALUE'] as $code => $val){ | |
| if(is_array($arValue['VALUE'][$code])){ | |
| $arValue['VALUE'][$code]['DEL'] = $val; | |
| } | |
| } | |
| } | |
| } | |
| //pre($_REQUEST); | |
| //pre($arProperty); | |
| //pre($arValue); | |
| //die(); | |
| /**/ | |
| $arFields = self::prepareSetting($arProperty['USER_TYPE_SETTINGS']); | |
| foreach($arValue['VALUE'] as $code => $value){ | |
| if($arFields[$code]['TYPE'] === 'file'){ | |
| $arValue['VALUE'][$code] = self::prepareFileToDB($value); | |
| } | |
| } | |
| //pre($arValue); | |
| //die(); | |
| $isEmpty = true; | |
| foreach ($arValue['VALUE'] as $v){ | |
| if(!empty($v)){ | |
| $isEmpty = false; | |
| break; | |
| } | |
| } | |
| if($isEmpty === false){ | |
| $arResult['VALUE'] = json_encode($arValue['VALUE']); | |
| } | |
| else{ | |
| $arResult = ['VALUE' => '', 'DESCRIPTION' => '']; | |
| } | |
| return $arResult; | |
| } | |
| public static function ConvertFromDB($arProperty, $arValue) | |
| { | |
| $return = array(); | |
| if(!empty($arValue['VALUE'])){ | |
| $arData = json_decode($arValue['VALUE'], true); | |
| foreach ($arData as $code => $value){ | |
| $return['VALUE'][$code] = $value; | |
| } | |
| } | |
| return $return; | |
| } | |
| //Internals | |
| private static function showString($code, $title, $arValue, $strHTMLControlName) | |
| { | |
| $result = ''; | |
| $v = !empty($arValue['VALUE'][$code]) ? htmlspecialchars($arValue['VALUE'][$code]) : ''; | |
| $result .= '<tr> | |
| <td align="right">'.$title.': </td> | |
| <td><input type="text" value="'.$v.'" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| return $result; | |
| } | |
| private static function showFile_OLD($code, $title, $arValue, $strHTMLControlName) | |
| { | |
| $result = ''; | |
| if(!empty($arValue['VALUE'][$code]) && !is_array($arValue['VALUE'][$code])){ | |
| $fileId = $arValue['VALUE'][$code]; | |
| } | |
| else if(!empty($arValue['VALUE'][$code]['OLD'])){ | |
| $fileId = $arValue['VALUE'][$code]['OLD']; | |
| } | |
| else{ | |
| $fileId = ''; | |
| } | |
| if(!empty($fileId)) | |
| { | |
| $arPicture = CFile::GetByID($fileId)->Fetch(); | |
| if($arPicture) | |
| { | |
| $strImageStorePath = COption::GetOptionString('main', 'upload_dir', 'upload'); | |
| $sImagePath = '/'.$strImageStorePath.'/'.$arPicture['SUBDIR'].'/'.$arPicture['FILE_NAME']; | |
| $fileType = self::getExtension($sImagePath); | |
| if(in_array($fileType, ['png', 'jpg', 'jpeg', 'gif'])){ | |
| $content = '<img src="'.$sImagePath.'">'; | |
| } | |
| else{ | |
| $content = '<div class="mf-file-name">'.$arPicture['FILE_NAME'].'</div>'; | |
| } | |
| $result = '<tr> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td> | |
| <table class="mf-img-table"> | |
| <tr> | |
| <td>'.$content.'<br> | |
| <div> | |
| <label><input name="'.$strHTMLControlName['VALUE'].'['.$code.'][DEL]" value="Y" type="checkbox"> '. Loc::getMessage("IEX_CPROP_FILE_DELETE") . '</label> | |
| <input name="'.$strHTMLControlName['VALUE'].'['.$code.'][OLD]" value="'.$fileId.'" type="hidden"> | |
| </div> | |
| </td> | |
| </tr> | |
| </table> | |
| </td> | |
| </tr>'; | |
| } | |
| } | |
| else{ | |
| $result .= '<tr> | |
| <td align="right">'.$title.': </td> | |
| <td><input type="file" value="" name="'.$strHTMLControlName['VALUE'].'['.$code.']"/></td> | |
| </tr>'; | |
| } | |
| return $result; | |
| } | |
| private static function showFile_OLD2($code, $title, $arValue, $strHTMLControlName) | |
| { | |
| $result = ''; | |
| if(!empty($arValue['VALUE'][$code]) && !is_array($arValue['VALUE'][$code])){ | |
| $fileId = $arValue['VALUE'][$code]; | |
| } | |
| else if(!empty($arValue['VALUE'][$code]['OLD'])){ | |
| $fileId = $arValue['VALUE'][$code]['OLD']; | |
| } | |
| else{ | |
| $fileId = ''; | |
| } | |
| if(!empty($fileId)) | |
| { | |
| $arPicture = CFile::GetByID($fileId)->Fetch(); | |
| if($arPicture) | |
| { | |
| $strImageStorePath = COption::GetOptionString('main', 'upload_dir', 'upload'); | |
| $sImagePath = '/'.$strImageStorePath.'/'.$arPicture['SUBDIR'].'/'.$arPicture['FILE_NAME']; | |
| $fileType = self::getExtension($sImagePath); | |
| if(in_array($fileType, ['png', 'jpg', 'jpeg', 'gif'])){ | |
| $content = '<img src="'.$sImagePath.'">'; | |
| } | |
| else{ | |
| $content = '<div class="mf-file-name">'.$arPicture['FILE_NAME'].'</div>'; | |
| } | |
| $result = '<tr> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td> | |
| <table class="mf-img-table"> | |
| <tr> | |
| <td>'.$content.'<br> | |
| <div> | |
| <label><input name="'.$strHTMLControlName['VALUE'].'['.$code.'][DEL]" value="Y" type="checkbox"> Удалить файл</label> | |
| <input name="'.$strHTMLControlName['VALUE'].'['.$code.'][OLD]" value="'.$fileId.'" type="hidden"> | |
| </div> | |
| </td> | |
| </tr> | |
| </table> | |
| </td> | |
| </tr>'; | |
| } | |
| } | |
| else{ | |
| $data = ''; | |
| if($strHTMLControlName["MODE"] === "FORM_FILL" && CModule::IncludeModule('fileman')) | |
| { | |
| $inputName = $strHTMLControlName['VALUE'].'['.$code.']'; | |
| $data = CFileInput::Show($inputName, $fileId, | |
| array( | |
| "PATH" => "Y", | |
| "IMAGE" => "Y", | |
| "MAX_SIZE" => array( | |
| "W" => COption::GetOptionString("iblock", "detail_image_size"), | |
| "H" => COption::GetOptionString("iblock", "detail_image_size"), | |
| ), | |
| ), array( | |
| 'upload' => true, | |
| 'medialib' => true, | |
| 'file_dialog' => true, | |
| 'cloud' => true, | |
| 'del' => true, | |
| 'description' => false, | |
| ) | |
| ); | |
| } | |
| $result .= '<tr> | |
| <td align="right">'.$title.': </td> | |
| <td>'.$data.' | |
| </td> | |
| </tr>'; | |
| } | |
| return $result; | |
| } | |
| private static function showFile($code, $title, $arValue, $strHTMLControlName, $wrapClass = false) | |
| { | |
| $result = ''; | |
| if(!empty($arValue['VALUE'][$code]) && !is_array($arValue['VALUE'][$code])){ | |
| $fileId = $arValue['VALUE'][$code]; | |
| } | |
| else if(!empty($arValue['VALUE'][$code]['OLD'])){ | |
| $fileId = $arValue['VALUE'][$code]['OLD']; | |
| } | |
| else{ | |
| $fileId = ''; | |
| } | |
| //if(!empty($fileId)) | |
| if(false) | |
| { | |
| $arPicture = CFile::GetByID($fileId)->Fetch(); | |
| if($arPicture) | |
| { | |
| $strImageStorePath = COption::GetOptionString('main', 'upload_dir', 'upload'); | |
| $sImagePath = '/'.$strImageStorePath.'/'.$arPicture['SUBDIR'].'/'.$arPicture['FILE_NAME']; | |
| $fileType = self::getExtension($sImagePath); | |
| if(in_array($fileType, ['png', 'jpg', 'jpeg', 'gif'])){ | |
| $content = '<img src="'.$sImagePath.'">'; | |
| } | |
| else{ | |
| $content = '<div class="mf-file-name">'.$arPicture['FILE_NAME'].'</div>'; | |
| } | |
| $result = '<tr class="'.$wrapClass.'"> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td> | |
| <table class="mf-img-table"> | |
| <tr> | |
| <td>'.$content.'<br> | |
| <div> | |
| <label><input name="'.$strHTMLControlName['VALUE'].'['.$code.'][DEL]" value="Y" type="checkbox"> Удалить файл</label> | |
| <input name="'.$strHTMLControlName['VALUE'].'['.$code.'][OLD]" value="'.$fileId.'" type="hidden"> | |
| </div> | |
| </td> | |
| </tr> | |
| </table> | |
| </td> | |
| </tr>'; | |
| } | |
| } | |
| else{ | |
| $data = ''; | |
| if($strHTMLControlName["MODE"] === "FORM_FILL" && CModule::IncludeModule('fileman')) | |
| { | |
| $inputName = $strHTMLControlName['VALUE'].'['.$code.']'; | |
| $data = CFileInput::Show($inputName, $fileId, | |
| array( | |
| "PATH" => "Y", | |
| "IMAGE" => "Y", | |
| "MAX_SIZE" => array( | |
| "W" => COption::GetOptionString("iblock", "detail_image_size"), | |
| "H" => COption::GetOptionString("iblock", "detail_image_size"), | |
| ), | |
| ), array( | |
| 'upload' => true, | |
| 'medialib' => true, | |
| 'file_dialog' => true, | |
| 'cloud' => true, | |
| 'del' => true, | |
| 'description' => false, | |
| ) | |
| ); | |
| } | |
| if($fileId){ | |
| $data .= '<input class="js_old_preview_picture" name="'.$strHTMLControlName['VALUE'].'['.$code.'][OLD]" value="'.$fileId.'" type="hidden">'; | |
| } | |
| $result .= '<tr class="'.$wrapClass.'"> | |
| <td align="right">'.$title.': </td> | |
| <td>'.$data.' | |
| </td> | |
| </tr>'; | |
| } | |
| return $result; | |
| } | |
| public static function showTextarea($code, $title, $arValue, $strHTMLControlName) | |
| { | |
| $result = ''; | |
| $v = !empty($arValue['VALUE'][$code]) ? $arValue['VALUE'][$code] : ''; | |
| $result .= '<tr> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td><textarea rows="8" name="'.$strHTMLControlName['VALUE'].'['.$code.']">'.$v.'</textarea></td> | |
| </tr>'; | |
| return $result; | |
| } | |
| public static function showDate($code, $title, $arValue, $strHTMLControlName) | |
| { | |
| $result = ''; | |
| $v = !empty($arValue['VALUE'][$code]) ? $arValue['VALUE'][$code] : ''; | |
| $result .= '<tr> | |
| <td align="right" valign="top">'.$title.': </td> | |
| <td> | |
| <table> | |
| <tr> | |
| <td style="padding: 0;"> | |
| <div class="adm-input-wrap adm-input-wrap-calendar"> | |
| <input class="adm-input adm-input-calendar" type="text" name="'.$strHTMLControlName['VALUE'].'['.$code.']" size="23" value="'.$v.'"> | |
| <span class="adm-calendar-icon" | |
| onclick="BX.calendar({node: this, field:\''.$strHTMLControlName['VALUE'].'['.$code.']\', form: \'\', bTime: true, bHideTime: false});"></span> | |
| </div> | |
| </td> | |
| </tr> | |
| </table> | |
| </td> | |
| </tr>'; | |
| return $result; | |
| } | |
| public static function showBindElement($code, $title, $arValue, $strHTMLControlName) | |
| { | |
| $result = ''; | |
| $v = !empty($arValue['VALUE'][$code]) ? $arValue['VALUE'][$code] : ''; | |
| $elUrl = ''; | |
| if(!empty($v)){ | |
| $arElem = \CIBlockElement::GetList([], ['ID' => $v],false, ['nPageSize' => 1], ['ID', 'IBLOCK_ID', 'IBLOCK_TYPE_ID', 'NAME'])->Fetch(); | |
| if(!empty($arElem)){ | |
| $elUrl .= '<a target="_blank" href="/bitrix/admin/iblock_element_edit.php?IBLOCK_ID='.$arElem['IBLOCK_ID'].'&ID='.$arElem['ID'].'&type='.$arElem['IBLOCK_TYPE_ID'].'">'.$arElem['NAME'].'</a>'; | |
| } | |
| } | |
| $result .= '<tr> | |
| <td align="right">'.$title.': </td> | |
| <td> | |
| <input name="'.$strHTMLControlName['VALUE'].'['.$code.']" id="'.$strHTMLControlName['VALUE'].'['.$code.']" value="'.$v.'" size="8" type="text" class="mf-inp-bind-elem"> | |
| <input type="button" value="..." onClick="jsUtils.OpenWindow(\'/bitrix/admin/iblock_element_search.php?lang=ru&IBLOCK_ID=0&n='.$strHTMLControlName['VALUE'].'&k='.$code.'\', 900, 700);"> | |
| <span>'.$elUrl.'</span> | |
| </td> | |
| </tr>'; | |
| return $result; | |
| } | |
| private static function showCss() | |
| { | |
| if(!self::$showedCss) { | |
| self::$showedCss = true; | |
| ?> | |
| <style> | |
| .cl {cursor: pointer;} | |
| .mf-gray {color: #797777;} | |
| .mf-fields-list {display: none; padding-top: 10px; margin-bottom: 10px!important; margin-left: -300px!important; border-bottom: 1px #e0e8ea solid!important;} | |
| .mf-fields-list.active {display: block;} | |
| .mf-fields-list td {padding-bottom: 5px;} | |
| .mf-fields-list td:first-child {width: 300px; color: #616060;} | |
| .mf-fields-list td:last-child {padding-left: 5px;} | |
| .mf-fields-list input[type="text"] {width: 350px!important;} | |
| .mf-fields-list textarea {min-width: 350px; max-width: 650px; color: #000;} | |
| .mf-fields-list img {max-height: 150px; margin: 5px 0;} | |
| .mf-img-table {background-color: #e0e8e9; color: #616060; width: 100%;} | |
| .mf-fields-list input[type="text"].adm-input-calendar {width: 170px!important;} | |
| .mf-file-name {word-break: break-word; padding: 5px 5px 0 0; color: #101010;} | |
| .mf-fields-list input[type="text"].mf-inp-bind-elem {width: unset!important;} | |
| .first-tab{ | |
| display:inherit; | |
| } | |
| .second-tab{ | |
| display:none; | |
| } | |
| .one-tab .first-tab{ | |
| display:none; | |
| } | |
| .one-tab .second-tab{ | |
| display:inherit; | |
| } | |
| .hidden-allways{ | |
| display:none; | |
| } | |
| </style> | |
| <? | |
| } | |
| } | |
| private static function showJs() | |
| { | |
| $showText = "Развернуть"; | |
| $hideText = "Свернуть"; | |
| $UpdateText = "Изменить"; | |
| $SeeText = "Посмотреть результат"; | |
| //self::$jsId = 'bx_file_'.mb_strtolower(preg_replace("/[^a-z0-9]/i", "_", $inputName)); | |
| CJSCore::Init(array("jquery")); | |
| if(!self::$showedJs) { | |
| self::$showedJs = true; | |
| ?> | |
| <script> | |
| function __VideoHostingGetFileObj(id){ | |
| let obj = false; | |
| $.each(window.ALL_FILE_INPUT, function(ind,val){ | |
| if(val.id == id){ | |
| obj = val; | |
| return true; | |
| } | |
| }); | |
| return obj; | |
| } | |
| function __VideoHostingParseHTML(html){ | |
| //https://www.youtube.com/watch?v=IfVOzfmNRLs | |
| function is_valid_url(urlString){ | |
| var urlPattern = new RegExp('^(https?:\\/\\/)?'+ // validate protocol | |
| '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // validate domain name | |
| '((\\d{1,3}\\.){3}\\d{1,3}))'+ // validate OR ip (v4) address | |
| '(\\:\\d+)?(\\/[-a-z\\d%_.~@+]*)*'+ // validate port and path | |
| '(\\?[;&a-z\\d%_.~+=-]*)?'+ // validate query string | |
| '(\\#[-a-z\\d_]*)?$','i'); // validate fragment locator | |
| return !!urlPattern.test(urlString); | |
| } | |
| function is_html(html){ | |
| let matches = html.match(/<[^<]+>/); | |
| if(!matches){ | |
| return false; | |
| } | |
| return true; | |
| //return preg_match("/<[^<]+>/",$string,$m) != 0; | |
| } | |
| function get_links_in_html(html){ | |
| let pattern = /(?:src|href)[\s]*=[\s]*(?:\"|')([\S]*)(?:\"|')/; | |
| let matches = html.match(pattern); | |
| return matches[1]; | |
| } | |
| let url = false; | |
| if(html){ | |
| if(is_html(html)){ | |
| url = get_links_in_html(html); | |
| }else { | |
| url = html; | |
| } | |
| } | |
| if(url){ | |
| if(is_valid_url(url)){ | |
| return url; | |
| } | |
| } | |
| return false; | |
| } | |
| function __VideoHostingDeleteImage(selector){ | |
| let wrap = false; | |
| if($(selector).hasClass('.adm-input-file-control')){ | |
| wrap = $(selector); | |
| }else{ | |
| wrap = $(selector).find('.adm-input-file-control'); | |
| } | |
| if(wrap.length>0){ | |
| let _cont_id = wrap.attr('id'); | |
| if(!!_cont_id){ | |
| let id = _cont_id.slice(0, -5); | |
| obj = __VideoHostingGetFileObj(id); | |
| } | |
| if(!!obj){ | |
| let PREVIEW_PIСTURE_OLD = $(selector).find("[name$='[OLD]']"); | |
| let FILE_ID = false; | |
| if(PREVIEW_PIСTURE_OLD.length>0){ | |
| FILE_ID = PREVIEW_PIСTURE_OLD.val(); | |
| } | |
| if(!!FILE_ID){ | |
| let SET_INDEX = 0; | |
| $.each(obj.arConfig.files, function(index,val){ | |
| if(val.ID == FILE_ID){ | |
| SET_INDEX = index; | |
| return false; | |
| } | |
| }); | |
| //SET_INDEX = _cont.find('[data-bx-meta]').attr('data-bx-meta'); | |
| obj.SetCurrentFile(SET_INDEX); | |
| obj.DeleteFile(true); | |
| } | |
| } | |
| } | |
| } | |
| function __VideoHostingSaveData(element, arData){ | |
| let HEADER = $(element).find("[name$='[HEADER]']"); | |
| if(HEADER.length>0){ | |
| HEADER.val(arData.title); | |
| } | |
| let DURATION = $(element).find("[name$='[DURATION]']"); | |
| if(DURATION.length>0){ | |
| DURATION.val(arData.duration); | |
| } | |
| let DIRECT_LINK = $(element).find("[name$='[DIRECT_LINK]']"); | |
| if(DIRECT_LINK.length>0){ | |
| DIRECT_LINK.val(arData.content_url); | |
| } | |
| let EMBED_LINK = $(element).find("[name$='[EMBED_LINK]']"); | |
| if(EMBED_LINK.length>0){ | |
| EMBED_LINK.val(arData.embed_url); | |
| } | |
| if(arData.thumbnail_url){ | |
| let PREVIEW_PIСTURE = $(element).find("[name$='[PREVIEW_PIСTURE]']"); | |
| if(PREVIEW_PIСTURE.length>0){ | |
| let obj = false; | |
| let _cont = PREVIEW_PIСTURE.closest('.adm-input-file-control'); | |
| let _cont_id = _cont.attr('id'); | |
| if(!!_cont_id){ | |
| let id = _cont_id.slice(0, -5); | |
| obj = __VideoHostingGetFileObj(id); | |
| } | |
| let CUR_IMAGE = false; | |
| let updateImage = true; | |
| if(!!obj){ | |
| let PREVIEW_PIСTURE_OLD = $(element).find("[name$='[PREVIEW_PIСTURE][OLD]']"); | |
| let FILE_ID = false; | |
| if(PREVIEW_PIСTURE_OLD.length>0){ | |
| FILE_ID = PREVIEW_PIСTURE_OLD.val(); | |
| } | |
| if(!!FILE_ID){ | |
| let SET_INDEX = 0; | |
| $.each(obj.arConfig.files, function(index,val){ | |
| if(val.ID == FILE_ID){ | |
| CUR_IMAGE = val; | |
| SET_INDEX = index; | |
| return false; | |
| } | |
| }); | |
| //SET_INDEX = _cont.find('[data-bx-meta]').attr('data-bx-meta'); | |
| if(!!CUR_IMAGE && !!arData.thumbnail){ | |
| if( | |
| CUR_IMAGE.ORIGINAL_NAME == arData.thumbnail.name | |
| && CUR_IMAGE.FILE_SIZE == arData.thumbnail.size | |
| && CUR_IMAGE.WIDTH == arData.thumbnail.width | |
| && CUR_IMAGE.HEIGHT == arData.thumbnail.height | |
| ){ | |
| updateImage = false; | |
| } | |
| } | |
| if(updateImage) { | |
| obj.SetCurrentFile(SET_INDEX); | |
| obj.DeleteFile(true); | |
| } | |
| } | |
| if(updateImage) { | |
| obj.ShowPath(); | |
| _cont.closest('tr').find('.js_old_preview_picture').attr('disabled', true); | |
| $(element).find("[name$='[PREVIEW_PIСTURE]']").val(arData.thumbnail_url); | |
| } | |
| } | |
| //console.log(arData); | |
| } | |
| } | |
| let PREVIEW = $(element).find(".js_video_hosting_preview"); | |
| let IFRAME_PREVIEW = $(element).find("[name$='[IFRAME_PREVIEW]']"); | |
| if(PREVIEW.length>0){ | |
| PREVIEW.empty(); | |
| PREVIEW.append(arData.embed_html); | |
| IFRAME_PREVIEW.val(arData.embed_html); | |
| } | |
| } | |
| function __VideoHostingHandleChange(_this){ | |
| let VALUE = _this.val(); | |
| let HASH = _this.data('hash'); | |
| let NEW_HASH = javaStringHashCode(VALUE); | |
| if(HASH != NEW_HASH){ | |
| let url = __VideoHostingParseHTML(_this.val()); | |
| console.log(url); | |
| if(url){ | |
| /* | |
| _this | |
| .closest('.js_custom_video_hosting') | |
| .find('.js_raw_input_value_parsed') | |
| .val(url);*/ | |
| var parent = _this | |
| .closest('.js_custom_video_hosting').get(0); | |
| $(parent).parent().find('.js-vh-error').remove(); | |
| BX.showWait(parent); | |
| $.ajax({ | |
| url: '/ajax/video_hosting.php', | |
| type: "post", | |
| dataType: "json", | |
| cache : true, | |
| data: { | |
| 'action':'get_data_by_url', | |
| 'url':url, | |
| }, | |
| }).done(function(data,status, jqXHR){ | |
| BX.closeWait(parent); //need if cache | |
| if(data.STATUS == "OK"){ | |
| __VideoHostingSaveData(parent,data.DATA); | |
| $(parent).addClass('one-tab'); | |
| $(parent).find('.vh-one-tab-toggle') | |
| .text('<?=$UpdateText?>'); | |
| }else{ | |
| if(!!data.MESSAGE){ | |
| $(parent).before('<span class="js-vh-error">'+data.MESSAGE+'</span>'); | |
| } | |
| } | |
| }).fail(function( jqXHR, textStatus, errorThrown){ | |
| //console.log(json); | |
| }).always(function( jqXHR, textStatus, errorThrown){ | |
| //console.log(jqXHR); | |
| BX.closeWait(parent); | |
| }); | |
| } | |
| _this.data('hash',NEW_HASH); | |
| } | |
| } | |
| /** | |
| * Returns a hash code from a string | |
| * @param {String} str The string to hash. | |
| * @return {Number} A 32bit integer | |
| * @see http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/ | |
| */ | |
| function hashCode(str) { | |
| let hash = 0; | |
| for (let i = 0, len = str.length; i < len; i++) { | |
| let chr = str.charCodeAt(i); | |
| hash = (hash << 5) - hash + chr; | |
| hash |= 0; // Convert to 32bit integer | |
| } | |
| return hash; | |
| } | |
| /* by chatgpt */ | |
| function javaStringHashCode(str) { | |
| let hash = 0; | |
| for (let i = 0; i < str.length; i++) { | |
| hash = (31 * hash + str.charCodeAt(i)) | 0; // Keep it 32-bit | |
| } | |
| return hash; | |
| } | |
| function onceOnEnd(func, limit){ | |
| var timeoutId; | |
| let start = new Date(); | |
| return function() { | |
| const args = arguments; | |
| const context = this; | |
| let current = new Date(); | |
| if (timeoutId) { | |
| clearTimeout(timeoutId); | |
| } | |
| //console.log("time " +(current - start)); | |
| start = current; | |
| timeoutId = setTimeout(function () { | |
| func.apply(context, args); | |
| }, limit); | |
| } | |
| } | |
| $(document).on('keyup', '.js_custom_video_hosting .js_raw_input_value', onceOnEnd(function (e) { | |
| var _this = $(this); | |
| __VideoHostingHandleChange(_this); | |
| },500)); | |
| $(document).on('paste', '.js_custom_video_hosting .js_raw_input_value', function (e) { | |
| var _this = $(this); | |
| // we can access input value on paste after some time | |
| setTimeout(function(){ | |
| // access element value | |
| __VideoHostingHandleChange(_this); | |
| },1); | |
| }); | |
| $(document).on('click', 'a.vh-one-tab-toggle', function (e) { | |
| e.preventDefault(); | |
| var table = $(this).closest('table'); | |
| $(table).toggleClass('one-tab'); | |
| if($(table).hasClass('one-tab')){ | |
| $(this).text('<?=$UpdateText?>'); | |
| } | |
| else{ | |
| $(this).text('<?=$SeeText?>'); | |
| } | |
| }); | |
| $(document).on('click', 'a.vh-toggle', function (e) { | |
| e.preventDefault(); | |
| var table = $(this).closest('tr').find('table.mf-fields-list'); | |
| $(table).toggleClass('active'); | |
| if($(table).hasClass('active')){ | |
| $(this).text('<?=$hideText?>'); | |
| } | |
| else{ | |
| $(this).text('<?=$showText?>'); | |
| } | |
| }); | |
| $(document).on('click', 'a.vh-delete', function (e) { | |
| e.preventDefault(); | |
| var textInputs = $(this).closest('tr').find('input[type="text"]'); | |
| $(textInputs).each(function (i, item) { | |
| $(item).val(''); | |
| }); | |
| var textarea = $(this).closest('tr').find('textarea'); | |
| $(textarea).each(function (i, item) { | |
| $(item).text(''); | |
| }); | |
| var checkBoxInputs = $(this).closest('tr').find('input[type="checkbox"]'); | |
| $(checkBoxInputs).each(function (i, item) { | |
| $(item).attr('checked', 'checked'); | |
| }); | |
| var html = $(this).closest('tr').find('.js_video_hosting_preview'); | |
| $(html).each(function (i, item) { | |
| $(item).empty(); | |
| }); | |
| __VideoHostingDeleteImage($(this).closest('tr')); | |
| //$(this).closest('tr').hide('slow'); | |
| }); | |
| // This is for multiple file type property (crutch) | |
| BX.ready(function(){ | |
| BX.addCustomEvent('onAddNewRowBeforeInner', function(data){ | |
| var html_string = data.html; | |
| var html_string2 = data.html; | |
| //tabs - clear tabs | |
| html_string2 = html_string2.replace("one-tab", ""); | |
| html_string2 = html_string2.replace("<?=$UpdateText?>", ""); | |
| html_string2 = html_string2.replace("<?=$SeeText?>", ""); | |
| data.html = html_string2; | |
| // If cloned property of cprop | |
| if($('<div>' + html_string + '</div>').find('table.mf-fields-list').length > 0){ | |
| var blocks = $(html_string).find('.adm-input-file-control.adm-input-file-top-shift'); | |
| if(blocks.length > 0){ | |
| document.cprop_endPos = 0; | |
| $(blocks).each(function (i, item) { | |
| blockId = $(item).attr('id'); | |
| if(blockId !== undefined && blockId !== null && blockId.length > 0){ | |
| setTimeout(function (i, blockId, html_string) { | |
| //blockId | |
| //tabs - clear tabs - backup | |
| $("#"+blockId).closest('.js_custom_video_hosting').removeClass('one-tab'); | |
| $("#"+blockId).closest('.js_custom_video_hosting').find('.vh-one-tab-toggle').text(''); | |
| // Remove hidden inputs | |
| var inputs = $('#' + blockId + ' .adm-input-file-new'); | |
| if(inputs !== undefined && inputs.length > 0){ | |
| inputs.each(function (i, item) { | |
| $(item).remove(); | |
| }) | |
| } | |
| var start_pos = html_string.indexOf("new top.BX.file_input", document.cprop_endPos); | |
| if(start_pos === -1){ | |
| start_pos = html_string.indexOf("new topWindow.BX.file_input", document.cprop_endPos); | |
| } | |
| var end_pos = html_string.indexOf(": new BX.file_input", start_pos); | |
| document.cprop_endPos = end_pos; | |
| let $what_add = "if(!window.ALL_FILE_INPUT_COUNT){"+ | |
| "window.ALL_FILE_INPUT_COUNT = 0;"+ | |
| "}"+ | |
| "if(!window.ALL_FILE_INPUT){"+ | |
| "window.ALL_FILE_INPUT = {};"+ | |
| "}"+ | |
| "window.ALL_FILE_INPUT_COUNT++;"+ | |
| "window.ALL_FILE_INPUT[window.ALL_FILE_INPUT_COUNT] = "; | |
| var jsCode = $what_add+html_string.substring(start_pos, end_pos); | |
| eval(jsCode); | |
| }, 500, i, blockId, html_string); | |
| } | |
| }); | |
| document.cprop_endPos = 0; | |
| } | |
| } | |
| }); | |
| }); | |
| </script> | |
| <? | |
| } | |
| } | |
| private static function showJsForSetting($inputName) | |
| { | |
| CJSCore::Init(array("jquery")); | |
| ?> | |
| <script> | |
| function addNewRows() { | |
| $("#many-fields-table").append('' + | |
| '<tr valign="top">' + | |
| '<td><input type="text" class="inp-code" size="20"></td>' + | |
| '<td><input type="text" class="inp-title" size="35"></td>' + | |
| '<td><input type="text" class="inp-sort" size="5" value="500"></td>' + | |
| '<td><select class="inp-type"><?=self::getOptionList()?></select></td>' + | |
| '</tr>'); | |
| } | |
| $(document).on('change', '.inp-code', function(){ | |
| var code = $(this).val(); | |
| if(code.length <= 0){ | |
| $(this).closest('tr').find('input.inp-title').removeAttr('name'); | |
| $(this).closest('tr').find('input.inp-sort').removeAttr('name'); | |
| $(this).closest('tr').find('select.inp-type').removeAttr('name'); | |
| } | |
| else{ | |
| $(this).closest('tr').find('input.inp-title').attr('name', '<?=$inputName?>[' + code + '_TITLE]'); | |
| $(this).closest('tr').find('input.inp-sort').attr('name', '<?=$inputName?>[' + code + '_SORT]'); | |
| $(this).closest('tr').find('select.inp-type').attr('name', '<?=$inputName?>[' + code + '_TYPE]'); | |
| } | |
| }); | |
| $(document).on('input', '.inp-sort', function(){ | |
| var num = $(this).val(); | |
| $(this).val(num.replace(/[^0-9]/gim,'')); | |
| }); | |
| </script> | |
| <? | |
| } | |
| private static function showCssForSetting() | |
| { | |
| if(!self::$showedCss) { | |
| self::$showedCss = true; | |
| ?> | |
| <style> | |
| .many-fields-table {margin: 0 auto; /*display: inline;*/} | |
| .mf-setting-title td {text-align: center!important; border-bottom: unset!important;} | |
| .many-fields-table td {text-align: center;} | |
| .many-fields-table > input, .many-fields-table > select{width: 90%!important;} | |
| .inp-sort{text-align: center;} | |
| .inp-type{min-width: 125px;} | |
| </style> | |
| <? | |
| } | |
| } | |
| /*from chatgpt*/ | |
| private static function javaStringHashCode($str) { | |
| $hash = 0; | |
| $n = strlen($str); | |
| for ($i = 0; $i < $n; $i++) { | |
| $hash = (31 * $hash + ord($str[$i])) & 0xFFFFFFFF; // Keep it within 32 bits | |
| } | |
| // Convert to signed integer | |
| /*if ($hash > 0x7FFFFFFF) { | |
| $hash -= 0x100000000; | |
| }*/ | |
| return $hash; | |
| } | |
| private static function prepareSetting($arSetting) | |
| { | |
| $arResult = []; | |
| /* | |
| foreach ($arSetting as $key => $value){ | |
| if(strstr($key, '_TITLE') !== false) { | |
| $code = str_replace('_TITLE', '', $key); | |
| $arResult[$code]['TITLE'] = $value; | |
| } | |
| else if(strstr($key, '_SORT') !== false) { | |
| $code = str_replace('_SORT', '', $key); | |
| $arResult[$code]['SORT'] = $value; | |
| } | |
| else if(strstr($key, '_TYPE') !== false) { | |
| $code = str_replace('_TYPE', '', $key); | |
| $arResult[$code]['TYPE'] = $value; | |
| } | |
| } | |
| if(!function_exists('cmp')){ | |
| function cmp($a, $b) | |
| { | |
| if ($a['SORT'] == $b['SORT']) { | |
| return 0; | |
| } | |
| return ($a['SORT'] < $b['SORT']) ? -1 : 1; | |
| } | |
| } | |
| uasort($arResult, 'cmp'); | |
| */ | |
| $arResult['INPUT_VALUE'] = array( | |
| 'CODE'=>'INPUT_VALUE', | |
| 'TITLE'=>'Введите текст или ссылку', | |
| 'SORT'=>100, | |
| 'TYPE'=>'text', | |
| ); | |
| $arResult['HEADER'] = array( | |
| 'CODE'=>'HEADER', | |
| 'TITLE'=>'Заголовок видео', | |
| 'SORT'=>100, | |
| 'TYPE'=>'string', | |
| ); | |
| $arResult['HEADER'] = array( | |
| 'CODE'=>'HEADER', | |
| 'TITLE'=>'Заголовок видео', | |
| 'SORT'=>100, | |
| 'TYPE'=>'string', | |
| ); | |
| $arResult['DIRECT_LINK'] = array( | |
| 'CODE'=>'DIRECT_LINK', | |
| 'TITLE'=>'Прямая ссылка', | |
| 'SORT'=>100, | |
| 'TYPE'=>'string', | |
| ); | |
| $arResult['EMBED_LINK'] = array( | |
| 'CODE'=>'EMBED_LINK', | |
| 'TITLE'=>'Встраиваемая ссылка', | |
| 'SORT'=>100, | |
| 'TYPE'=>'string', | |
| ); | |
| $arResult['PREVIEW_PIСTURE'] = array( | |
| 'CODE'=>'PREVIEW_PIСTURE', | |
| 'TITLE'=>'Изображение превью', | |
| 'SORT'=>100, | |
| 'TYPE'=>'file', | |
| ); | |
| $arResult['DURATION'] = array( | |
| 'CODE'=>'DURATION', | |
| 'TITLE'=>'Длительность видео', | |
| 'SORT'=>100, | |
| 'TYPE'=>'string', | |
| ); | |
| $arResult['IFRAME_PREVIEW'] = array( | |
| 'CODE'=>'IFRAME_PREVIEW', | |
| 'TITLE'=>'Встраивание превью', | |
| 'SORT'=>100, | |
| 'TYPE'=>'text', | |
| ); | |
| return $arResult; | |
| } | |
| private static function getOptionList($selected = 'string') | |
| { | |
| $result = ''; | |
| $arOption = [ | |
| 'string' => Loc::getMessage('IEX_CPROP_FIELD_TYPE_STRING'), | |
| 'file' => Loc::getMessage('IEX_CPROP_FIELD_TYPE_FILE'), | |
| 'text' => Loc::getMessage('IEX_CPROP_FIELD_TYPE_TEXT'), | |
| 'date' => Loc::getMessage('IEX_CPROP_FIELD_TYPE_DATE'), | |
| 'element' => Loc::getMessage('IEX_CPROP_FIELD_TYPE_ELEMENT') | |
| ]; | |
| foreach ($arOption as $code => $name){ | |
| $s = ''; | |
| if($code === $selected){ | |
| $s = 'selected'; | |
| } | |
| $result .= '<option value="'.$code.'" '.$s.'>'.$name.'</option>'; | |
| } | |
| return $result; | |
| } | |
| private static function prepareFileToDB($arValue) | |
| { | |
| $result = false; | |
| if(!empty($arValue['DEL']) && $arValue['DEL'] === 'Y' && !empty($arValue['OLD'])){ | |
| CFile::Delete($arValue['OLD']); | |
| } | |
| // ВАЖНО сначало проверяем name | |
| else if(!empty($arValue['name']) && $arValue['error'] == 0){ | |
| $result = CFile::SaveFile($arValue, 'vote'); | |
| } | |
| // ВАЖНО после проверяем OLD | |
| else if(!empty($arValue['OLD'])){ | |
| $result = $arValue['OLD']; | |
| } | |
| else if(!empty($arValue) && is_file($_SERVER['DOCUMENT_ROOT'] . $arValue)){ | |
| $arFile = CFile::MakeFileArray($_SERVER['DOCUMENT_ROOT'] . $arValue); | |
| $result = CFile::SaveFile($arFile, 'vote'); | |
| } | |
| else if(!empty($arValue) && filter_var($arValue, FILTER_VALIDATE_URL)){ | |
| $arFile = CFile::MakeFileArray($arValue); | |
| $result = CFile::SaveFile($arFile, 'vote'); | |
| } | |
| return $result; | |
| } | |
| private static function getExtension($filePath) | |
| { | |
| return array_pop(explode('.', $filePath)); | |
| } | |
| } | |
| $eventManager = \Bitrix\Main\EventManager::getInstance(); | |
| $eventManager->addEventHandler('iblock', 'OnIBlockPropertyBuildList', 'CIBlockPropertyCustomVideoHostingProp::GetUserTypeDescription'); | |
| // добавляем код что бы получить доступ к js коду картинок | |
| AddEventHandler("main", "OnEndBufferContent", "ChangeMyContent"); | |
| function ChangeMyContent(&$content) | |
| { | |
| $what_find = "(topWindow.BX.file_input) ? new topWindow.BX.file_input"; | |
| $what_add = "if(!window.ALL_FILE_INPUT_COUNT){ | |
| window.ALL_FILE_INPUT_COUNT = 0; | |
| } | |
| if(!window.ALL_FILE_INPUT){ | |
| window.ALL_FILE_INPUT = {}; | |
| } | |
| window.ALL_FILE_INPUT_COUNT++; | |
| window.ALL_FILE_INPUT[window.ALL_FILE_INPUT_COUNT] = "; | |
| $content = str_replace($what_find, $what_add.$what_find, $content); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment