mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 09:49:28 +02:00
This commit is contained in:
parent
d14af6c6c9
commit
e562f6ff91
2 changed files with 197 additions and 233 deletions
78
plugin/BulkEmbed/search.json.php
Normal file
78
plugin/BulkEmbed/search.json.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
require_once '../../videos/configuration.php';
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!User::isLogged()) {
|
||||
die(json_encode(['error' => 'You must be logged in to search']));
|
||||
}
|
||||
|
||||
$query = $_POST['query'] ?? '';
|
||||
$pageToken = $_POST['pageToken'] ?? '';
|
||||
|
||||
if (empty($query)) {
|
||||
die(json_encode(['error' => 'Search query cannot be empty']));
|
||||
}
|
||||
|
||||
$obj = AVideoPlugin::getObjectData("BulkEmbed");
|
||||
$apiKey = $obj->API_KEY;
|
||||
|
||||
// Construct the YouTube API URL with pagination (if pageToken is provided)
|
||||
$youtubeApiUrl = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=" . urlencode($query) . "&type=video&maxResults=50&videoEmbeddable=true&key=" . $apiKey;
|
||||
|
||||
if (!empty($pageToken)) {
|
||||
$youtubeApiUrl .= "&pageToken=" . $pageToken;
|
||||
}
|
||||
|
||||
$response = file_get_contents($youtubeApiUrl);
|
||||
$responseData = json_decode($response, true);
|
||||
|
||||
if (empty($responseData) || !isset($responseData['items'])) {
|
||||
die(json_encode(['error' => 'Failed to retrieve data from YouTube']));
|
||||
}
|
||||
|
||||
// Prepare the result array to include the embedding status
|
||||
$results = [];
|
||||
|
||||
foreach ($responseData['items'] as $item) {
|
||||
if (!isset($item['id']['videoId'])) {
|
||||
continue; // Skip if videoId is not present
|
||||
}
|
||||
|
||||
$videoId = $item['id']['videoId'];
|
||||
$link = "https://youtube.com/embed/" . $videoId;
|
||||
|
||||
// Check if the video is already embedded in the database
|
||||
$isEmbedded = false;
|
||||
$embeddedVideoId = null;
|
||||
|
||||
$sql = "SELECT id, videoLink FROM `videos` WHERE `videoLink` = ? LIMIT 1";
|
||||
$res = sqlDAL::readSql($sql, "s", [$link]);
|
||||
$data = sqlDAL::fetchAssoc($res);
|
||||
sqlDAL::close($res);
|
||||
|
||||
if (!empty($data['id'])) {
|
||||
$isEmbedded = true;
|
||||
$embeddedVideos_Id = $data['id']; // Capture the videoId when already embedded
|
||||
}
|
||||
|
||||
// Add item data to results
|
||||
$results[] = [
|
||||
'link' => $link,
|
||||
'videoId' => $videoId,
|
||||
'title' => $item['snippet']['title'],
|
||||
'description' => $item['snippet']['description'],
|
||||
'thumbs' => $item['snippet']['thumbnails']['high']['url'],
|
||||
'date' => $item['snippet']['publishedAt'],
|
||||
'isEmbedded' => $isEmbedded,
|
||||
'embeddedVideos_Id' => $embeddedVideos_Id // Add embedded videoId if embedded
|
||||
];
|
||||
}
|
||||
|
||||
// Return the data and pagination tokens to the client
|
||||
die(json_encode([
|
||||
'data' => [
|
||||
'items' => $results,
|
||||
'nextPageToken' => $responseData['nextPageToken'] ?? null,
|
||||
'prevPageToken' => $responseData['prevPageToken'] ?? null
|
||||
]
|
||||
]));
|
|
@ -95,7 +95,7 @@ $_page = new Page(array('Search'));
|
|||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<form id="search-form" name="search-form" onsubmit="return search()">
|
||||
<form id="search-form" name="search-form">
|
||||
<div id="custom-search-input">
|
||||
<div class="input-group col-md-12">
|
||||
<input type="search" id="query" class="form-control input-lg" placeholder="Search YouTube / PlayList URL" />
|
||||
|
@ -124,23 +124,24 @@ $_page = new Page(array('Search'));
|
|||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var gapikey = '<?php echo $obj->API_KEY; ?>';
|
||||
var playListName = '';
|
||||
|
||||
$(function() {
|
||||
$('#search-form').submit(function(e) {
|
||||
e.preventDefault();
|
||||
search(); // Call the new search function
|
||||
});
|
||||
|
||||
$('#getAll').click(function() {
|
||||
var videoLink = new Array();
|
||||
var videoLink = [];
|
||||
$("input:checkbox[name=videoCheckbox]").each(function() {
|
||||
videoLink.push($(this).val());
|
||||
});
|
||||
saveIt(videoLink);
|
||||
});
|
||||
|
||||
$('#getSelected').click(function() {
|
||||
var videoLink = new Array();
|
||||
var videoLink = [];
|
||||
$("input:checkbox[name=videoCheckbox]:checked").each(function() {
|
||||
videoLink.push($(this).val());
|
||||
});
|
||||
|
@ -148,49 +149,6 @@ $_page = new Page(array('Search'));
|
|||
});
|
||||
});
|
||||
|
||||
function saveIt(videoLink) {
|
||||
modal.showPleaseWait();
|
||||
setTimeout(function() {
|
||||
var itemsToSave = [];
|
||||
for (x in videoLink) {
|
||||
if (typeof videoLink[x] === 'function') {
|
||||
continue;
|
||||
}
|
||||
$.ajax({
|
||||
url: "https://www.googleapis.com/youtube/v3/videos?id=" + videoLink[x] + "&part=id,snippet,contentDetails&key=" + gapikey,
|
||||
async: false,
|
||||
success: function(data) {
|
||||
var item = {};
|
||||
item.link = "https://youtube.com/embed/" + data.items[0].id;
|
||||
item.title = data.items[0].snippet.title;
|
||||
item.description = data.items[0].snippet.description;
|
||||
item.duration = data.items[0].contentDetails.duration;
|
||||
item.thumbs = data.items[0].snippet.thumbnails.high.url;
|
||||
item.date = data.items[0].snippet.publishedAt;
|
||||
console.log(data.items[0].snippet, item);
|
||||
itemsToSave.push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
$.ajax({
|
||||
url: webSiteRootURL + 'plugin/BulkEmbed/save.json.php',
|
||||
data: {
|
||||
"itemsToSave": itemsToSave,
|
||||
playListName: playListName
|
||||
},
|
||||
type: 'post',
|
||||
success: function(response) {
|
||||
if (!response.error) {
|
||||
avideoAlertSuccess(__("Your videos have been saved!"));
|
||||
} else {
|
||||
avideoAlertError(response.msg.join("<br>"));
|
||||
}
|
||||
modal.hidePleaseWait();
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function validURL(str) {
|
||||
var pattern = new RegExp('^(https?:\\/\\/)?' + // protocol
|
||||
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
|
||||
|
@ -223,227 +181,155 @@ $_page = new Page(array('Search'));
|
|||
return false;
|
||||
}
|
||||
|
||||
function search() {
|
||||
// clear
|
||||
function search(pageToken = '') {
|
||||
// Clear previous results
|
||||
$('#results').html('');
|
||||
$('#buttons').html('');
|
||||
|
||||
// get form input
|
||||
q = $('#query').val(); // this probably shouldn't be created as a global
|
||||
var query = $('#query').val();
|
||||
|
||||
var playListId = getPlayListId(q);
|
||||
|
||||
if (playListId) {
|
||||
$.get(
|
||||
"https://www.googleapis.com/youtube/v3/playlists", {
|
||||
part: 'snippet',
|
||||
key: gapikey,
|
||||
id: playListId
|
||||
},
|
||||
function(data) {
|
||||
playListName = data.items[0].snippet.title;
|
||||
$.get(
|
||||
"https://www.googleapis.com/youtube/v3/playlistItems", {
|
||||
part: 'snippet, id',
|
||||
q: q,
|
||||
type: 'video',
|
||||
key: gapikey,
|
||||
maxResults: 50,
|
||||
videoEmbeddable: "true",
|
||||
videoSyndicated: "true",
|
||||
playlistId: playListId
|
||||
},
|
||||
function(data) {
|
||||
processData(data);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
playListName = '';
|
||||
// run get request on API
|
||||
$.get(
|
||||
"https://www.googleapis.com/youtube/v3/search", {
|
||||
part: 'snippet, id',
|
||||
q: q,
|
||||
type: 'video',
|
||||
key: gapikey,
|
||||
maxResults: 50,
|
||||
videoSyndicated: "true",
|
||||
videoEmbeddable: "true"
|
||||
},
|
||||
function(data) {
|
||||
processData(data);
|
||||
});
|
||||
}
|
||||
// Make AJAX call to the PHP search page
|
||||
$.ajax({
|
||||
url: webSiteRootURL + 'plugin/BulkEmbed/search.json.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
query: query,
|
||||
pageToken: pageToken
|
||||
},
|
||||
success: function(response) {
|
||||
//console.log(response); // Log the full response here
|
||||
if (response.error) {
|
||||
avideoAlertError(response.error);
|
||||
} else {
|
||||
processData(response.data);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.log("An error occurred: " + error);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function processData(data) {
|
||||
var nextPageToken = data.nextPageToken;
|
||||
var prevPageToken = data.prevPageToken;
|
||||
// Check if items array exists
|
||||
if (!data || !data.items || !Array.isArray(data.items)) {
|
||||
console.error('Invalid data format received from the server:', data);
|
||||
avideoAlertError("Invalid data format received from the server");
|
||||
return;
|
||||
}
|
||||
|
||||
// Log data
|
||||
//console.log(data);
|
||||
// Clear previous data
|
||||
$('#results').html('');
|
||||
$('#buttons').html('');
|
||||
|
||||
// Process each item
|
||||
$.each(data.items, function(i, item) {
|
||||
// Get Output
|
||||
var output = getOutput(item);
|
||||
|
||||
// display results
|
||||
$('#results').append(output);
|
||||
});
|
||||
|
||||
var buttons = getButtons(prevPageToken, nextPageToken);
|
||||
|
||||
// Display buttons
|
||||
// Handle pagination buttons
|
||||
var buttons = getButtons(data.prevPageToken, data.nextPageToken);
|
||||
$('#buttons').append(buttons);
|
||||
}
|
||||
|
||||
// Next page function
|
||||
function nextPage() {
|
||||
var token = $('#next-button').data('token');
|
||||
var q = $('#next-button').data('query');
|
||||
|
||||
|
||||
// clear
|
||||
$('#results').html('');
|
||||
$('#buttons').html('');
|
||||
|
||||
// get form input
|
||||
q = $('#query').val(); // this probably shouldn't be created as a global
|
||||
|
||||
// run get request on API
|
||||
$.get(
|
||||
"https://www.googleapis.com/youtube/v3/search", {
|
||||
part: 'snippet, id',
|
||||
q: q,
|
||||
pageToken: token,
|
||||
type: 'video',
|
||||
key: gapikey,
|
||||
maxResults: 50,
|
||||
videoEmbeddable: "true"
|
||||
},
|
||||
function(data) {
|
||||
|
||||
var nextPageToken = data.nextPageToken;
|
||||
var prevPageToken = data.prevPageToken;
|
||||
|
||||
// Log data
|
||||
console.log(data);
|
||||
|
||||
$.each(data.items, function(i, item) {
|
||||
|
||||
// Get Output
|
||||
var output = getOutput(item);
|
||||
|
||||
// display results
|
||||
$('#results').append(output);
|
||||
});
|
||||
|
||||
var buttons = getButtons(prevPageToken, nextPageToken);
|
||||
|
||||
// Display buttons
|
||||
$('#buttons').append(buttons);
|
||||
});
|
||||
function nextPage(token) {
|
||||
var query = $('#query').val();
|
||||
search(token);
|
||||
}
|
||||
|
||||
// Previous page function
|
||||
function prevPage() {
|
||||
var token = $('#prev-button').data('token');
|
||||
var q = $('#prev-button').data('query');
|
||||
|
||||
|
||||
// clear
|
||||
$('#results').html('');
|
||||
$('#buttons').html('');
|
||||
|
||||
// get form input
|
||||
q = $('#query').val(); // this probably shouldn't be created as a global
|
||||
|
||||
// run get request on API
|
||||
$.get(
|
||||
"https://www.googleapis.com/youtube/v3/search", {
|
||||
part: 'snippet, id',
|
||||
q: q,
|
||||
pageToken: token,
|
||||
type: 'video',
|
||||
key: gapikey,
|
||||
maxResults: 50,
|
||||
videoEmbeddable: "true"
|
||||
},
|
||||
function(data) {
|
||||
|
||||
var nextPageToken = data.nextPageToken;
|
||||
var prevPageToken = data.prevPageToken;
|
||||
|
||||
// Log data
|
||||
console.log(data);
|
||||
|
||||
$.each(data.items, function(i, item) {
|
||||
|
||||
// Get Output
|
||||
var output = getOutput(item);
|
||||
|
||||
// display results
|
||||
$('#results').append(output);
|
||||
});
|
||||
|
||||
var buttons = getButtons(prevPageToken, nextPageToken);
|
||||
|
||||
// Display buttons
|
||||
$('#buttons').append(buttons);
|
||||
});
|
||||
function prevPage(token) {
|
||||
var query = $('#query').val();
|
||||
search(token);
|
||||
}
|
||||
|
||||
// Build output
|
||||
function getOutput(item) {
|
||||
console.log(item);
|
||||
var videoID;
|
||||
if (typeof item.snippet.thumbnails === 'undefined') {
|
||||
return true;
|
||||
}
|
||||
if (item.id.videoId) {
|
||||
videoID = item.id.videoId;
|
||||
} else {
|
||||
videoID = item.snippet.resourceId.videoId;
|
||||
}
|
||||
var title = item.snippet.title;
|
||||
var description = item.snippet.description;
|
||||
var thumb = item.snippet.thumbnails.high.url;
|
||||
var channelTitle = item.snippet.channelTitle;
|
||||
var videoDate = item.snippet.publishedAt;
|
||||
|
||||
// Build output string
|
||||
var output = '<li>' +
|
||||
'<div class="list-left">' +
|
||||
'<img src="' + thumb + '">' +
|
||||
'</div>' +
|
||||
'<div class="list-left">';
|
||||
|
||||
if (item.isEmbedded) {
|
||||
// Apply grayscale effect to the image for embedded videos
|
||||
output += '<img src="' + item.thumbs + '" style="filter: grayscale(100%);">';
|
||||
} else {
|
||||
// Regular image for non-embedded videos
|
||||
output += '<img src="' + item.thumbs + '">';
|
||||
}
|
||||
|
||||
output += '</div>' +
|
||||
'<div class="list-right">' +
|
||||
'<h3><input type="checkbox" value="' + videoID + '" name="videoCheckbox"> <a target="_blank" href="https://youtube.com/embed/' + videoID + '?rel=0">' + title + '</a></h3>' +
|
||||
'<small>By <span class="cTitle">' + channelTitle + '</span> on ' + videoDate + '</small>' +
|
||||
'<p>' + description + '</p>' +
|
||||
'<h3>';
|
||||
|
||||
if (item.isEmbedded) {
|
||||
// If the video is embedded, show only the title and indicate it's already embedded
|
||||
output += '<i class="fa-regular fa-square-check"></i> <a target="_blank" href="' + item.link + '" target="_blank">' + item.title + '</a>';
|
||||
output += '<p><a class="btn btn-danger" href="' + webSiteRootURL + 'video/' + item.embeddedVideos_Id + '">'+__('Already embedded')+'</strong></a>';
|
||||
} else {
|
||||
// If the video is not embedded, include a checkbox for embedding
|
||||
output += '<input type="checkbox" value="' + item.link + '" name="videoCheckbox"> ';
|
||||
output += '<a target="_blank" href="' + item.link + '">' + item.title + '</a>';
|
||||
}
|
||||
|
||||
output += '</h3>' +
|
||||
'<small>Published on ' + item.date + '</small>' +
|
||||
'<p>' + item.description + '</p>' +
|
||||
'</div>' +
|
||||
'</li>' +
|
||||
'<div class="clearfix"></div>' +
|
||||
'';
|
||||
'</li>';
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
function getButtons(prevPageToken, nextPageToken) {
|
||||
if (!prevPageToken) {
|
||||
var btnoutput = '<div class="button-container">' +
|
||||
'<button id="next-button" class="paging-button" data-token="' + nextPageToken + '" data-query="' + q + '"' +
|
||||
'onclick = "nextPage();">Next Page</button>' +
|
||||
'</div>';
|
||||
} else {
|
||||
var btnoutput = '<div class="button-container">' +
|
||||
'<button id="prev-button" class="paging-button" data-token="' + prevPageToken + '" data-query="' + q + '"' +
|
||||
'onclick = "prevPage();">Prev Page</button>' +
|
||||
'<button id="next-button" class="paging-button" data-token="' + nextPageToken + '" data-query="' + q + '"' +
|
||||
'onclick = "nextPage();">Next Page</button>' +
|
||||
var buttons = '';
|
||||
|
||||
if (prevPageToken) {
|
||||
buttons += '<div class="button-container">' +
|
||||
'<button id="prev-button" class="paging-button" data-token="' + prevPageToken + '" onclick="prevPage(\'' + prevPageToken + '\')">Prev Page</button>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
return btnoutput;
|
||||
if (nextPageToken) {
|
||||
buttons += '<div class="button-container">' +
|
||||
'<button id="next-button" class="paging-button" data-token="' + nextPageToken + '" onclick="nextPage(\'' + nextPageToken + '\')">Next Page</button>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
// Save selected videos
|
||||
function saveIt(videoLink) {
|
||||
modal.showPleaseWait();
|
||||
setTimeout(function() {
|
||||
var itemsToSave = [];
|
||||
$.each(videoLink, function(index, link) {
|
||||
itemsToSave.push({
|
||||
link: link
|
||||
});
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: webSiteRootURL + 'plugin/BulkEmbed/save.json.php',
|
||||
data: {
|
||||
"itemsToSave": itemsToSave,
|
||||
playListName: playListName
|
||||
},
|
||||
type: 'POST',
|
||||
success: function(response) {
|
||||
if (!response.error) {
|
||||
avideoAlertSuccess(__("Your videos have been saved!"));
|
||||
} else {
|
||||
avideoAlertError(response.msg.join("<br>"));
|
||||
}
|
||||
modal.hidePleaseWait();
|
||||
}
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue