Last active
April 13, 2024 10:16
-
-
Save EscApp2/c7ab584e3488dfe3d145a464197350e7 to your computer and use it in GitHub Desktop.
Get Vk video thumb thumbnail embed iframe
This file contains 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
.youtube_auto_wrap{ | |
position:relative; | |
} | |
.youtube_auto_wrap .youtube_auto_wrap__preview{ | |
z-index: 10; | |
top: 0; | |
bottom: 0px; | |
left: 0px; | |
right: 0px; | |
cursor: pointer; | |
position: absolute; | |
} | |
@media (max-width: 640px){ | |
.youtube_auto_wrap .youtube_auto_wrap__preview img{ | |
height: 100%; | |
width: 100%; | |
} | |
} | |
.youtube_auto_wrap .youtube_auto_wrap__preview:before{ | |
z-index: 15; | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
-webkit-transform: translate(-50%, -50%); | |
-ms-transform: translate(-50%, -50%); | |
transform: translate(-50%, -50%); | |
content: " "; | |
background-repeat: no-repeat; | |
background-size: cover; | |
width: 110px; | |
height: 70px; | |
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='800' width='1200' viewBox='-35.20005 -41.33325 305.0671 247.9995'%3E%3Cpath d='M229.763 25.817c-2.699-10.162-10.65-18.165-20.748-20.881C190.716 0 117.333 0 117.333 0S43.951 0 25.651 4.936C15.553 7.652 7.6 15.655 4.903 25.817 0 44.236 0 82.667 0 82.667s0 38.429 4.903 56.85C7.6 149.68 15.553 157.681 25.65 160.4c18.3 4.934 91.682 4.934 91.682 4.934s73.383 0 91.682-4.934c10.098-2.718 18.049-10.72 20.748-20.882 4.904-18.421 4.904-56.85 4.904-56.85s0-38.431-4.904-56.85' fill='red'/%3E%3Cpath d='M93.333 117.559l61.333-34.89-61.333-34.894z' fill='%23fff'/%3E%3C/svg%3E"); | |
} | |
.youtube_auto_wrap .youtube_auto_wrap__iframe { | |
position: relative; | |
padding-bottom: 56.25%; /* 16:9 */ | |
height: 0; | |
display:block;/*important*/ | |
} | |
.youtube_auto_wrap .youtube_auto_wrap__iframe iframe { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
} | |
This file contains 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
AddEventHandler("main", "OnEndBufferContent", "deleteH1ForStyle2", 50); | |
function deleteH1ForStyle2(&$content) { | |
global $PAGE_STYLE_2; | |
if($PAGE_STYLE_2){ | |
$content = preg_replace( | |
'/<!--\s*remove\s*block\s*([^-]*)\s*-->[\s\S]*<!--\s*remove\s*block\s*(\1)\s*end\s*-->/im', | |
'', | |
$content); | |
// ищем iframe | |
$pattern ="/<iframe"; | |
$pattern .="(?![^>]*\bskip-youtube-auto-wrap\b)"; // у которого нет артибута или класса или id "skip-youtube-auto-wrap" | |
//$pattern .="(?=[^>]*\bskip-wrap\b)"; // у которого есть артибут или класса или id "skip-wrap" | |
$pattern .="[^>]*\bsrc\s*=[\'\\\"]([^\s]+(youtube|youtu\.be)[^\s]+)[\'\\\"]"; // у которого в src строка без пробелов с youtube или youtu.be | |
$pattern .="[^>]*>\s*<\s*\/iframe\s*>/mi"; // | |
$output = preg_replace_callback($pattern, function($matches){ | |
$iframe = $matches[0]; | |
$remove_height_pattern = "/(height\s*=\s*[\'\\\"]([^'|\\\"]+)[\'\\\"])/mi"; | |
$iframe = preg_replace($remove_height_pattern, "",$iframe); | |
$id = __YoutubeVideo::get_youtube_id($matches[1]); | |
$url = $matches[1]; | |
$arParts = parse_url($url); | |
if($arParts['query']){ | |
$url = $url."&enablejsapi=1"; | |
}else{ | |
$url = $url."?enablejsapi=1"; | |
} | |
$iframe = str_replace($matches[1],$url,$iframe); | |
if($id){ | |
$arData = __YoutubeVideo::getVideoData($matches[1]); | |
$meta_json = __YoutubeVideo::createVideoMicrodata($arData,true); | |
ob_start(); | |
?> | |
<div class="youtube_auto_wrap"> | |
<script> | |
var playTube = function(elem){ | |
var youtubePlayer = $(elem).parent('.youtube_auto_wrap').find('iframe').get(0); | |
if (youtubePlayer) { | |
youtubePlayer.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); | |
}; | |
$(elem).hide(); | |
} | |
</script> | |
<div class='youtube_auto_wrap__preview' | |
onclick="playTube(this)" | |
> | |
<picture> | |
<source | |
srcset="https://img.youtube.com/vi/<?=$id?>/maxresdefault.jpg" | |
media="(min-width: 641px)" | |
> | |
<img | |
src="https://img.youtube.com/vi/<?=$id?>/sddefault.jpg" | |
alt="" | |
> | |
</picture> | |
</div> | |
<div class='youtube_auto_wrap__iframe'> | |
<?=$iframe?> | |
</div> | |
<?=$meta_json?> | |
</div> | |
<? | |
$iframe = ob_get_contents(); | |
ob_end_clean(); | |
} | |
return $iframe; | |
},$content); | |
if($output){ | |
$content = $output; | |
unset($output); | |
} | |
} | |
} |
This file contains 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
<? | |
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 __VkVideo { /*__VkVideoIframe*/ | |
public static function getVkVideoIframe($url){ | |
$arUrl = parse_url($url); | |
if($arUrl['host'] == "vk.com"){ | |
if($arUrl['path'] == "/video_ext.php"){ | |
//embed | |
//return $url."&autoplay=1"; | |
$ob_uri = new \Bitrix\Main\Web\Uri($url); | |
$ob_uri->addParams(array('autoplay'=>1)); | |
return $ob_uri->getUri(); | |
}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."&autoplay=1"; | |
$ob_uri = new \Bitrix\Main\Web\Uri($href); | |
$ob_uri->addParams(array('autoplay'=>1)); | |
return $ob_uri->getUri(); | |
} | |
} | |
} | |
return false; | |
} | |
public static function getVkVideoCachedIframe($url){ | |
$arData = false; | |
$obCache = new \CPHPCache(); | |
$time = 30*24*3600; | |
$uniq_string = __METHOD__.md5($url)."autoplay"; | |
if ($obCache->InitCache($time, $uniq_string, "/__VkVideo/".__FUNCTION__."/")) | |
{ | |
$arData = $obCache->GetVars(); | |
} | |
elseif ($obCache->StartDataCache()) | |
{ | |
$arData['embedUrl'] = self::getVkVideoIframe($url); | |
$obCache->EndDataCache($arData); | |
} | |
return $arData['embedUrl']; | |
} | |
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; | |
} | |
//isServiceUrl | |
public static function getVkVideoId($url){ | |
$arUrl = parse_url($url); | |
if($arUrl['host'] == "vk.com"){ | |
if($arUrl['path'] == "/video_ext.php"){ | |
//embed | |
$arQuery = array(); | |
parse_str($arUrl['query'], $arQuery); | |
$id = $arQuery['oid']."_".$arQuery['id']; | |
return $id; | |
}elseif(strpos($arUrl['path'], '/video-')!==false){ | |
$id = str_replace("/video-","",$arUrl['path']); | |
return $id; | |
} | |
} | |
return false; | |
} | |
public static function getVkVideoCachedThumbnail($url){ | |
$arUrl = parse_url($url); | |
if($arUrl['host'] == "vk.com"){ | |
$embedUrl = self::getVkVideoCachedIframe($url); | |
if($embedUrl){ | |
$id = self::getVkVideoId($url); | |
$DIR = '/video/thumbs/vk'; | |
if(!is_file($_SERVER['DOCUMENT_ROOT'].$DIR."/".$id.'.jpg')){ | |
$picture_url = self::getVkVideoThumbnail($embedUrl); | |
if($picture_url){ | |
$pic = file_get_contents($picture_url); // получаем данные. Ответ от сайта | |
if($pic && strlen($pic)>0){ | |
if(!is_dir($_SERVER['DOCUMENT_ROOT'].$DIR)){ | |
mkdir($_SERVER['DOCUMENT_ROOT'].$DIR, 0777, true); | |
} | |
file_put_contents($_SERVER['DOCUMENT_ROOT'].$DIR."/".$id.".jpg", $pic); // сохраняем полученную картинку | |
} | |
} | |
} | |
if(!is_file($_SERVER['DOCUMENT_ROOT'].$DIR."/".$id.'.jpg')){ | |
return false; | |
} | |
return $DIR.'/'.$id.'.jpg'; | |
} | |
} | |
return false; | |
} | |
} |
This file contains 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
<? | |
class __WorkWithVideo{ | |
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; | |
} | |
function getHandler($url){ | |
// "__VkVideoIframe" | |
$arClassList = array("Vk","Youtube"); | |
foreach($arClassList as $class){ | |
$class_name = "__".$class."VideoIframe"; | |
if($class_name::isServiceUrl($url)){ | |
return $class_name; | |
} | |
} | |
return false; | |
} | |
} |
This file contains 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
<? | |
class HLHelp{ | |
public static function getHLDataId($idCodeName) { | |
\Bitrix\Main\Loader::includeModule('highloadblock'); | |
$filter = array(); | |
if (empty($idCodeName)) { | |
return false; | |
} | |
if (intval($idCodeName) > 0) { | |
return $idCodeName; | |
} else { | |
$filter[] = [ | |
'LOGIC' => 'OR', | |
'TABLE_NAME' => $idCodeName, | |
'NAME' => $idCodeName | |
]; | |
} | |
$hlBlock = Bitrix\Highloadblock\HighloadBlockTable::getList(array( | |
'filter' => $filter | |
))->fetch(); | |
if ($hlBlock) { | |
return $hlBlock['ID']; | |
} else { | |
return false; | |
} | |
} | |
public static function getHLDataClass($idCodeName) { | |
\Bitrix\Main\Loader::includeModule('highloadblock'); | |
$filter = array(); | |
if (empty($idCodeName)) { | |
return false; | |
} | |
if (intval($idCodeName) > 0) { | |
$filter['ID'] = $idCodeName; | |
} else { | |
$filter[] = [ | |
'LOGIC' => 'OR', | |
'TABLE_NAME' => $idCodeName, | |
'NAME' => $idCodeName | |
]; | |
} | |
$hlBlock = Bitrix\Highloadblock\HighloadBlockTable::getList(array( | |
'filter' => $filter | |
))->fetch(); // �������� ������ ������ HL ����� | |
if ($hlBlock) { | |
$entity = Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hlBlock); // �������� ������� �������� | |
return $entity->getDataClass(); // �������� ��������� ������ | |
} else { | |
return false; | |
} | |
} | |
public static function camel_to_snake($input) | |
{ | |
//https://gist.github.com/carousel/1aacbea013d230768b3dec1a14ce5751 | |
return strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $input)); | |
} | |
/** | |
* $code - camel case required | |
*/ | |
public static function createHLDataTable($code, $title){ | |
$class = self::getHLDataClass($code); | |
if($class){ | |
return $class; | |
} | |
$arLangs = Array( | |
'ru' => $title, | |
); | |
\Bitrix\Main\Loader::includeModule('highloadblock'); | |
$result = Bitrix\Highloadblock\HighloadBlockTable::add(array( | |
'NAME' => $code, | |
'TABLE_NAME' => "hl_".self::camel_to_snake($code), | |
)); | |
if ($result->isSuccess()) { | |
$id = $result->getId(); | |
foreach($arLangs as $lang_key => $lang_val){ | |
Bitrix\Highloadblock\HighloadBlockLangTable::add(array( | |
'ID' => $id, | |
'LID' => $lang_key, | |
'NAME' => $lang_val | |
)); | |
} | |
$class = self::getHLDataClass($id); | |
if($class){ | |
return $class; | |
} | |
} else { | |
$errors = $result->getErrorMessages(); | |
var_dump($errors); | |
} | |
return false; | |
} | |
public static function createHlUserFieldTypeString($CODE, $NAME, $IBLOCK_ID){ | |
$arFields = Array( | |
"ENTITY_ID" => "HLBLOCK_".$IBLOCK_ID, | |
"FIELD_NAME" => "UF_".$CODE, | |
"USER_TYPE_ID" => "string", | |
"XML_ID" => "", | |
"SORT" => "1500", | |
"MULTIPLE" => "N", | |
"MANDATORY" => "N", | |
"EDIT_FORM_LABEL" => array('ru'=>$NAME), | |
"LIST_COLUMN_LABEL" => array('ru'=>$NAME), | |
"LIST_FILTER_LABEL" => array('ru'=>$NAME), | |
"ERROR_MESSAGE" => "", | |
"HELP_MESSAGE" => "", | |
); | |
$UF_ID = 0; | |
$rsData = CUserTypeEntity::GetList( array(), array('ENTITY_ID'=>$arFields['ENTITY_ID'], 'FIELD_NAME'=>$arFields['FIELD_NAME']) ); | |
if($arRes = $rsData->Fetch()) | |
{ | |
$UF_ID = $arRes['ID']; | |
} | |
$obUserField = new CUserTypeEntity; | |
if($UF_ID > 0){ | |
//$res = $obUserField->Update($UF_ID, $arFields); | |
}else | |
{ | |
$UF_ID = $obUserField->Add($arFields); | |
} | |
} | |
} | |
class HelpVideoData{ | |
static $HL_CODE = 'VideoCache'; //Название сущности должно начинаться с заглавной буквы и состоять только из латинских букв и цифр | |
public static function createDB(){ | |
if(!HLHelp::getHLDataClass(self::$HL_CODE)){ | |
$video = HLHelp::createHLDataTable(self::$HL_CODE, 'Данные о видео для микроразметки'); | |
if($video){ | |
$HlId = HLHelp::getHLDataId(self::$HL_CODE); | |
HLHelp::createHlUserFieldTypeString('PLATFORM', 'Платформа' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('CODE', 'Код' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('NAME', 'Название видео' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('DESCRIPTION', 'Описание видео' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('THUMBNAIL_URL', 'URL обложки видео' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('UPLOAD_DATE', 'Дата загрузки видео' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('DURATION', 'Длительность видео' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('CONTENT_URL', 'URL видео' ,$HlId); | |
HLHelp::createHlUserFieldTypeString('EMBED_URL', 'Url встроенного в код видео' ,$HlId); | |
} | |
} | |
} | |
public static function findVideo($platform,$code){ | |
if($class = HLHelp::getHLDataClass(self::$HL_CODE)){ | |
$res = $class::getList(array( | |
'filter'=>array( | |
"UF_CODE"=>$code, | |
"UF_PLATFORM"=>$platform, | |
) | |
)); | |
if($arData = $res->Fetch()){ | |
return $arData; | |
} | |
} | |
return false; | |
} | |
public static function saveVideo($platform, $code, $inputSaveData){ | |
if($class = HLHelp::getHLDataClass(self::$HL_CODE)){ | |
$res = $class::getList(array( | |
'filter'=>array( | |
"UF_CODE"=>$code, | |
"UF_PLATFORM"=>$platform, | |
) | |
)); | |
$saveData = array(); | |
foreach($inputSaveData as $key=>$val){ | |
if($key == "ID"){ | |
continue; | |
} | |
$saveData["UF_".$key] = $val; | |
} | |
if($arData = $res->Fetch()){ | |
unset($saveData['UF_CODE']); | |
unset($saveData['UF_PLATFORM']); | |
$result = $class::update($arData['ID'],$saveData); | |
if ($result->isSuccess()) | |
{ | |
return true; | |
} | |
}else{ | |
$result = $class::add($saveData); | |
if ($result->isSuccess()) | |
{ | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
} | |
class __YoutubeVideo { | |
public static function is_html($string) | |
{ | |
//https://stackoverflow.com/a/18242528 | |
return preg_match("/<[^<]+>/",$string,$m) != 0; | |
} | |
public static function get_youtube_link_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_youtube_id($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 false; | |
} | |
public static function getVideoDataFromSite($url){ | |
$body = file_get_contents($url); | |
$doc = new DOMDocument(); | |
@$doc->loadHTML( '<meta charset="utf8">' .$body ); | |
$xpath = new DOMXpath($doc); | |
//https://github.com/dpb587/microdata-dom.php/blob/master/src/MicrodataDOM/DOMDocument.php | |
$arReturn = array(); | |
$arDuration = $xpath->query('//*[@itemprop="duration"]'); | |
foreach($arDuration as $element){ | |
$arReturn['DURATION'] = $element->getAttribute('content'); | |
break; | |
} | |
$arUploadData = $xpath->query('//*[@itemprop="uploadDate"]'); | |
foreach($arUploadData as $element){ | |
$arReturn['UPLOAD_DATE'] = $element->getAttribute('content'); | |
break; | |
} | |
$arTitle = $xpath->query('//*[@property="og:title"]'); | |
foreach($arTitle as $element){ | |
$arReturn['NAME'] = $element->getAttribute('content'); | |
break; | |
} | |
$arDescription = $xpath->query('//*[@name="twitter:description"]'); | |
foreach($arDescription as $element){ | |
$arReturn['DESCRIPTION'] = $element->getAttribute('content'); | |
break; | |
} | |
return $arReturn; | |
} | |
public static function getVideoData($rawInput){ | |
if(self::is_html($rawInput)){ | |
$url = self::get_youtube_link_in_html($rawInput); | |
if($url){ | |
$id = self::get_youtube_id($url); | |
} | |
}elseif(filter_var($rawInput, FILTER_VALIDATE_URL) !== false){ | |
$id = self::get_youtube_id($rawInput); | |
} | |
/*else{ | |
$id = $rawInput; | |
}*/ | |
if($id){ | |
$arData = array( | |
"PLATFORM"=>"youtube", | |
"CODE"=>$id, | |
); | |
$data = HelpVideoData::findVideo($arData['PLATFORM'],$arData['CODE']); | |
if($data){ | |
return $data; | |
}else{ | |
$contentURL = self::getContentUrl($id); | |
$arServerData = self::getVideoDataFromSite($contentURL); | |
if(is_array($arServerData) && count($arServerData)>0){ | |
$arData['DURATION'] = $arServerData['DURATION']; | |
$arData['NAME'] = $arServerData['NAME']; | |
$arData['DESCRIPTION'] = $arServerData['DESCRIPTION']; | |
$Odj = date_create_from_format(DATE_ISO8601,$arServerData['UPLOAD_DATE']);// | |
if($Odj){ | |
$arData['UPLOAD_DATE'] = $Odj->getTimestamp(); | |
} | |
$arData['CONTENT_URL'] = $contentURL; | |
$arData['EMBED_URL'] = self::getEmbedUrl($id); | |
$arData['THUMBNAIL_URL'] = self::getThumbnailUrl($id); | |
$result = HelpVideoData::saveVideo($arData['PLATFORM'],$arData['CODE'], $arData); | |
if($result){ | |
return HelpVideoData::findVideo($arData['PLATFORM'],$arData['CODE']); | |
} | |
} | |
} | |
} | |
return false; | |
} | |
public static function createVideoMicrodata($arData, $return = false ){ | |
global $APPLICATION; | |
$arData = [ | |
"@context"=>"https://schema.org", | |
"@type"=>"VideoObject", | |
"name"=>htmlspecialcharsbx($arData['UF_NAME']), | |
"description"=>htmlspecialcharsbx($arData['UF_DESCRIPTION']), | |
"thumbnailUrl"=>htmlspecialcharsbx(URN2URI($arData['UF_THUMBNAIL_URL'])), | |
"uploadDate"=>date(DATE_ISO8601,$arData['UF_UPLOAD_DATE']), | |
"duration"=>$arData['UF_DURATION'], | |
"contentUrl"=>$arData['UF_CONTENT_URL'], | |
"embedUrl"=>$arData['UF_EMBED_URL'], | |
]; | |
$meta = '<script class="video" type="application/ld+json">' . json_encode($arData) . '</script>'; | |
if($return){ | |
return $meta; | |
} | |
$APPLICATION->AddHeadString($meta ,true); | |
} | |
} |
This file contains 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
<? | |
$arMicroData = __YoutubeVideo::getVideoData($arItem["PROPERTIES"]["LINK_VIDEO"]["VALUE"]); | |
__YoutubeVideo::createVideoMicrodata($arMicroData); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment