Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/urlpreview/parser/ |
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/urlpreview/parser/common.php |
<?php namespace Bitrix\Main\UrlPreview\Parser; use Bitrix\Main\UrlPreview\HtmlDocument; use Bitrix\Main\UrlPreview\Parser; use Bitrix\Main\Web\Uri; class Common extends Parser { const MIN_IMAGE_HEIGHT = 100; const MIN_IMAGE_WIDTH = 100; /** @var array img elements, discovered in the document */ protected $imgElements = array(); /** * Parses HTML document's meta tags, and fills document's metadata. * * @param HtmlDocument $document HTML document to scan for metadata. * @return void */ public function handle(HtmlDocument $document) { if($document->getTitle() == '') { $document->setTitle($this->getTitle($document)); } if($document->getDescription() == '') { $document->setDescription($document->getMetaContent('description')); } $this->imgElements = $document->extractElementAttributes('img'); if($document->getImage() == '') { $image = $this->getImage($document); if($image <> '') { $document->setImage($image); } else { $imageCandidates = $this->getImageCandidates(); if(count($imageCandidates) === 1) { $document->setImage($imageCandidates[0]); } else if(count($imageCandidates) > 1) { $document->setExtraField('IMAGES', $imageCandidates); } } } if($document->getExtraField('VIDEO') == '') { preg_match_all("/<video.+?<\/video>/mis", $document->getHtml(), $videoTags); foreach($videoTags[0] as $videoTag) { $videoInfo = $this->getVideoInfo($videoTag); if(!empty($videoInfo)) { $document->setExtraField('VIDEO', $videoInfo['src']); $document->setExtraField('VIDEO_TYPE', $videoInfo['type']); $document->setExtraField('VIDEO_WIDTH', $videoInfo['width']); $document->setExtraField('VIDEO_HEIGHT', $videoInfo['height']); } } } } /** * @param HtmlDocument $document HTML document to scan for title. * @return string */ protected function getTitle(HtmlDocument $document) { $title = $document->getMetaContent('title'); if($title <> '') { return $title; } preg_match('/<title>(.+?)<\/title>/mis', $document->getHtml(), $matches); return ($matches[1] ?? null); } /** * @param HtmlDocument $document * @return string */ protected function getImage(HtmlDocument $document) { $result = $document->getLinkHref('image_src'); if($result <> '') { return $result; } foreach($this->imgElements as $imgElement) { if(isset($imgElement['rel']) && $imgElement['rel'] == 'image_src') { $result = $imgElement['src']; return $result; } } return null; } /** * Iterates through img elements, and return array of urls of images, which size is greater then 100pxx100px * @return array */ protected function getImageCandidates() { $result = array(); foreach ($this->imgElements as $imgElement) { $imageDimensions = $this->getImageDimensions($imgElement); if($imageDimensions['width'] >= self::MIN_IMAGE_WIDTH && $imageDimensions['height'] >= self::MIN_IMAGE_HEIGHT) { $result[] = $imgElement['src']; } } return $result; } /** * Returns size of the img element * @param array $imageAttributes Array of the attributes of the img tag. * @return array Returns array with keys width and height. */ protected function getImageDimensions(array $imageAttributes) { $result = array( 'width' => null, 'height' => null ); foreach(array_keys($result) as $imageDimension) { if(isset($imageAttributes[$imageDimension])) { $result[$imageDimension] = $imageAttributes[$imageDimension]; } else if(isset($imageAttributes['style']) && preg_match('/'.$imageDimension.':\s*(\d+?)px/', $imageAttributes['style'], $matches)) { $result[$imageDimension] = $matches[1]; } } return $result; } /** * Parse one <video> tag and try to get valid information off it. * * @param string $html - one <video> from the document. * @return array */ protected function getVideoInfo($html = '') { $maxWeight = -1; $result = array(); $uri = new Uri('/'); $document = new HtmlDocument($html, $uri); $videoElements = $document->extractElementAttributes('video'); foreach ($videoElements as $videoElement) { if (!isset($videoElement['src'])) { $sourceElements = $document->extractElementAttributes('source'); foreach ($sourceElements as $sourceElement) { if ( isset($sourceElement['type']) && $this->isValidVideoMimeType($sourceElement['type']) ) { $videoElement['src'] = $sourceElement['src']; $videoElement['type'] = $sourceElement['type']; break; } } } if (isset($videoElement['src'])) { if ( (isset($videoElement['width']) && isset($videoElement['height']) && (int)$videoElement['width'] * (int)$videoElement['height'] > $maxWeight) || (empty($result)) ) { $result = $videoElement; $maxWeight = 0; if(isset($videoElement['width']) && isset($videoElement['height'])) { $maxWeight = (int)$videoElement['width'] * (int)$videoElement['height']; } } } } return $result; } /** * Returns true if $type is a valid video mime-type. * * @param string $type * @return bool */ protected function isValidVideoMimeType($type = '') { if(empty($type)) { return false; } static $validTypes = array( 'video/mp4', 'video/x-flv', 'video/webm', 'video/ogg', 'video/quicktime' ); return in_array($type, $validTypes); } }