Плагин парсинга данных видео с YouTube и VK для MODX

Плагин для парсинга видеороликов с YouTube и VK. Парсит заголовок, картинку и ссылку для использования фрейма.

Обязательно должен быть установлен компоненты pdoTools, MIGX и библиотека cURL на сервере.

Создаём TV с типом MIGX, называем VideoGallery

Вкладки формы

[
  {
    "caption": "Заголовок",
    "fields": [
      {
        "field": "link_video",
        "caption": "Ссылка на видео",
        "inputTVtype": "text"
      },
      {
        "field": "title",
        "caption": "Название",
        "inputTVtype": "text"
      },
      {
        "field": "image",
        "caption": "Постер",
        "inputTVtype": "image",
        "sourceFrom": "migx"
      },
      {
        "field": "link_frame",
        "caption": "frame(Заполняется автоматически)",
        "inputTVtype": "text"
      }
    ]
  }
]

Разметка колонок

[{
  "header": "Ссылка на видео",
  "dataIndex": "link_video"
},{
  "header": "Название",
  "dataIndex": "title"
},{
  "renderer": "this.renderImage",
  "sourceFrom": "migx",
  "header": "Постер",
  "dataIndex": "image"
},{
  "header": "frame(Заполняется автоматически)",
  "dataIndex": "link_frame"
}]

 

Создаём плагин, например ParsingVideo

Подвязываем на событие OnDocFormSave (сохранение документа)

/*
* Пример отдачи в JSON
* YouTube - https://www.googleapis.com/youtube/v3/videos?id=YykjpeuMNEk&part=snippet%2Cstatistics%2CcontentDetails&key=Токен
* VK - https://api.vk.com/method/video.get?videos=-29581998_456239066&access_token=Токен&v=V
*/
// Функция для соединения и парсинга
function get_ydata($url) {
    $ch = curl_init();
    $timeout = 5;
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}
function translit($str) {
  $str = (string) $str;
  $str = strip_tags($str);
  $str = str_replace(array("\n", "\r"), " ", $str);
  $str = preg_replace("/\s+/", ' ', $str);
  $str = trim($str); // убираем пробелы в начале и конце строки
  $str = function_exists('mb_strtolower') ? mb_strtolower($str) : strtolower($str);
  $ABC = array('а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'j','з'=>'z','и'=>'i',
  'й'=>'y','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u',
  'ф'=>'f','х'=>'h','ц'=>'c','ч'=>'ch','ш'=>'sh','щ'=>'shch','ы'=>'y','э'=>'e','ю'=>'yu','я'=>'ya','ъ'=>'','ь'=>'');
  $str = strtr($str, $ABC);
  $str = preg_replace("/[^0-9a-z-_ ]/i", "", $str);
  $str = str_replace(" ", "-", $str);
  return $str;
} 

//Функция для сохранения изображения через CURL
function save_image($img,$path){
  $curl = curl_init($img);
  curl_setopt($curl, CURLOPT_HEADER, 0);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_BINARYTRANSFER,1);
  $content = curl_exec($curl);
  curl_close($curl);

  if (file_exists($path)) :
    unlink($path);
  endif;
  $fp = fopen($path,'x');
  fwrite($fp, $content);
  fclose($fp);
}

// создаём новые параметры в системных настройках или указываем вручную
$YouTubeKEY = $modx->getOption('AccessTokenYouTube',''); // access_token YouTube
$vkKEY = $modx->getOption('AccessTokenVK',''); // access_token VK

$resource = $modx->getObject('modResource', $resource->get('id')); // получаем id текущего, редактируемого русурса
$VideoGallery = $resource->getTVValue('VideoGallery'); // получаем значение поля Галереи
$i = '0';
foreach (json_decode($VideoGallery, true) as $VideoItem ) { // Основной цикл. Идём по полям
    $IdTV = $VideoItem['MIGX_id'];
    $link = $VideoItem['link_video'];
    $titleTV =  $VideoItem['title'];
    $imageTV = $VideoItem['image'];
    

    if (strpos($link, 'youtube.com') == true) { //YouTube video
        $array_link = explode("=", $link);
        $id_link = explode("&", $array_link[1]);
        $VideoID = $id_link[0];
        
        $api_url = "https://www.googleapis.com/youtube/v3/videos?id=".$VideoID."&part=snippet%2Cstatistics%2CcontentDetails&key=".$YouTubeKEY; //Формируем урл запрос к базе YouTube

        $json_curl = get_ydata($api_url); // парсим файл с информацией о видео (curl)
        $youtube = json_decode($json_curl); // преобразовали JSON-строку в объект PHP
        foreach ($youtube->items as $itemY) { // проходимся по массиву, задавая переменные
            $title = $itemY->snippet->title; // заголовок
            $thumb = $itemY->snippet->thumbnails; // превью
            }
            // забираем урл для превью видео. Какой есть.
            if ($thumb->maxres->url) {
            $thumb = $thumb ? $thumb->maxres->url : $thumb->maxres->url;
            }
            elseif ($thumb->standard->url) {
            $thumb = $thumb ? $thumb->standard->url : $thumb->standard->url; 
            }
            elseif ($thumb->high->url) {
            $thumb = $thumb ? $thumb->high->url : $thumb->high->url; 
            }
            else {
            $thumb = $thumb ? $thumb->medium->url : $thumb->medium->url; 
            }
        $LinkVideo = 'https://www.youtube.com/watch?v='.$VideoID;
    }
    
    if (strpos($link, 'vk.com')  == true) { //VK video
        $array_link = explode("video", $link);
        if (substr_count($link,"video") == 2) {
            $id_link = explode("%", $array_link[2]);
            $VideoID = $id_link[0];
        } else {
            $VideoID = $array_link[1];
        }
        
        $videoGet = file_get_contents("https://api.vk.com/method/video.get?videos=".$VideoID."&access_token=".$vkKEY."&v=V");
        $video = json_decode($videoGet,1);
        $title = $video["response"][1]["title"];
        $thumb = $video["response"][1]["image_medium"];
        $LinkVideo = $video["response"][1]["player"];
        if (strpos($LinkVideo, 'youtube.com')): // если видео было добавлено в VK с YouTube забирираем ссылку
           $LinkVideo = 'https://www.youtube.com/watch?v='.substr($LinkVideo, -11);
        endif;
    }
    if (!$imageTV) { // если поле картинки не было заполнено в админке, копируем на сервер
        $ImgName = translit($title); // заголовок переводим транслитом. Это будет название картинки
        $thumbNew = '.../assets/images/galleryVideo/'.$ImgName.'.jpg'; // полный путь
        if (!save_image($thumb, $thumbNew)) { // Сохраняем файл
        $modx->log(xPDO::LOG_LEVEL_ERROR, 'Не удалось скопировать файл'.$thumb.' в в директорию '.$thumbNew.'. ID ресурса - '.$resource->get('id'));
        }
    $thumb = '/assets/images/galleryVideo/'.$ImgName.'.jpg';
    }
    else {
        $thumb = $imageTV;
    }
    $title = $titleTV ?: $title; // если поле заголовок было заполнено вручную оставляем
    // формируем массив для перезаписи полей
    $VideoARRAY[$i] =  array ( 'MIGX_id' => $IdTV, 'link_video' => $link, 'title' => $title, 'image' => $thumb, 'link_frame' => $LinkVideo, );
    $i++;
}

$arrNewValue = json_encode($VideoARRAY); // Окончательный Массив в JSON
// Сохраняем спарсенные значения
if (!$resource->setTVValue('VideoGallery', $arrNewValue)) {
    $modx->log(xPDO::LOG_LEVEL_ERROR, 'Проблемы с сохранением поля VideoGallery. ID ресурса - '.$resource->get('id'));
}

 

Создаём сниппет для вывода — VideoGallery

/*
* Обязательные параметры
* chunk - для вывода видео (Имя чанка или @INLINE)
* VideoGallery - значение поля MIGX
*
* Параметры для использования в чанке
* {$thumb} - Превью
* {$title} - Заголовок видео
* {$url} - ссылка на видео
* {$chunk} - Чанк для вывода
*
* Вызов
* {'VideoGallery' | snippet : [ 'chunk' => 'ItemVideo', 'VideoGallery' => $_modx->resource.VideoGallery ]}
*/
$pdo = $modx->getService('pdoFetch');
foreach (json_decode($VideoGallery, true) as $VideoItem ) { // Основной цикл. Идём по полям
    $link_frame = $VideoItem['link_frame'];
    $titleTV =  $VideoItem['title'];
    $imageTV = $VideoItem['image'];
    // Вывод результата
    $output = $pdo->getChunk($chunk, array('thumb' => $imageTV, 'title' => $titleTV, 'url' => $link_frame));
    echo $output;
}