Skip to content

Commit

Permalink
Merge pull request #22 from nyx-ei/feature/search-youtube-video
Browse files Browse the repository at this point in the history
Feature/search youtube video
  • Loading branch information
karimalik authored Sep 7, 2024
2 parents c165aa5 + 7b73234 commit f03ca0e
Show file tree
Hide file tree
Showing 12 changed files with 340 additions and 31 deletions.
60 changes: 60 additions & 0 deletions local/youtubesearch/add_to_course.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

/**
* @package youtubesearch
* @copyright 2024 NYX-EI {@link https://nyx-ei.tech}
* @author NYX-EI <help@nyx-ei.tech>
*/

require_once(__DIR__ . '/../../config.php');
require_login();

$video_id = required_param('video_id', PARAM_ALPHANUMEXT);
$course_id = required_param('course_id', PARAM_INT);

$course = $DB->get_record('course', array('id' => $course_id), '*', MUST_EXIST);
$context = context_course::instance($course->id);
require_capability('moodle/course:manageactivities', $context);

// Add the YouTube video as a URL resource to the course
$module = $DB->get_record('modules', array('name' => 'url'), '*', MUST_EXIST);

$url_instance = new stdClass();
$url_instance->course = $course_id;
$url_instance->name = "YouTube Video: " . $video_id;
$url_instance->intro = "";
$url_instance->introformat = FORMAT_HTML;
$url_instance->externalurl = "https://www.youtube.com/watch?v=" . $video_id;
$url_instance->display = RESOURCELIB_DISPLAY_EMBED;
$url_instance->displayoptions = serialize(array(
'printheading' => 1,
'printintro' => 0,
'printlastmodified' => 1,
'width' => 640,
'height' => 360,
'popupwidth' => 620,
'popupheight' => 450
));
$url_instance->timemodified = time();
$url_instance->section = 0; // Add to the first section of the course

$url_instance->id = $DB->insert_record('url', $url_instance);

$module_instance = new stdClass();
$module_instance->course = $course_id;
$module_instance->module = $module->id;
$module_instance->instance = $url_instance->id;
$module_instance->section = 0;
$module_instance->added = time();

$module_instance->id = $DB->insert_record('course_modules', $module_instance);

// Update the section
$section = $DB->get_record('course_sections', array('course' => $course_id, 'section' => 0));
$section->sequence = trim($section->sequence . ',' . $module_instance->id, ',');
$DB->update_record('course_sections', $section);

rebuild_course_cache($course_id);

header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => get_string('video_added', 'local_youtubesearch')]);
59 changes: 59 additions & 0 deletions local/youtubesearch/amd/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
define(['jquery'], function($) {
return {
init: function() {
$('#youtube-search-form').on('submit', function(e) {
e.preventDefault();
var query = $('input[name="q"]').val();
$.ajax({
url: M.cfg.wwwroot + '/local/youtubesearch/search.php',
data: { q: query },
dataType: 'json',
success: function(results) {
var html = '';
if (results && results.length > 0) {
results.forEach(function(video) {
html += '<div class="youtube-video-item">';
html += '<img src="' + video.snippet.thumbnails.default.url + '" alt="' + video.snippet.title + '">';
html += '<h3>' + video.snippet.title + '</h3>';
html += '<button onclick="previewVideo(\'' + video.id.videoId + '\')">Preview</button>';
html += '<button onclick="addToCourse(\'' + video.id.videoId + '\')">Add to course</button>';
html += '</div>';
});
} else {
html = '<p>' + M.util.get_string('noresults', 'local_youtubesearch') + '</p>';
}
$('#youtube-search-results').html(html);
},
error: function() {
$('#youtube-search-results').html('<p>An error occurred while searching.</p>');
}
});
});

window.previewVideo = function(videoId) {
var previewUrl = 'https://www.youtube.com/embed/' + videoId;
window.open(previewUrl, 'YouTube Preview', 'width=640,height=360');
};

window.addToCourse = function(videoId) {
var courseId = M.cfg.courseId;
$.ajax({
url: M.cfg.wwwroot + '/local/youtubesearch/add_to_course.php',
data: { video_id: videoId, course_id: courseId },
dataType: 'json',
method: 'POST',
success: function(response) {
if (response.success) {
alert(M.util.get_string('video_added', 'local_youtubesearch'));
} else {
alert(M.util.get_string('error_adding_video', 'local_youtubesearch'));
}
},
error: function() {
alert(M.util.get_string('error_adding_video', 'local_youtubesearch'));
}
});
};
}
};
});
15 changes: 15 additions & 0 deletions local/youtubesearch/db/access.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
defined('MOODLE_INTERNAL') || die();

$capabilities = [
'local/youtubesearch:use' => [
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
]
];
36 changes: 36 additions & 0 deletions local/youtubesearch/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/**
* @package youtubesearch
* @copyright 2024 NYX-EI {@link https://nyx-ei.tech}
* @author NYX-EI <help@nyx-ei.tech>
*/

require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot . '/local/youtubesearch/lib.php');

require_login();

require_capability('local/youtubesearch:use', context_system::instance());

$PAGE->set_url(new moodle_url('/local/youtubesearch/index.php'));
$PAGE->set_context(context_system::instance());
$PAGE->set_title(get_string('pluginname', 'local_youtubesearch'));
$PAGE->set_heading(get_string('pluginname', 'local_youtubesearch'));

$PAGE->requires->js_call_amd('local_youtubesearch/main', 'init');
$PAGE->requires->css('/local/youtubesearch/styles.css');

echo $OUTPUT->header();

$search_form = '
<form id="youtube-search-form">
<input type="text" name="q" placeholder="' . get_string('search_placeholder', 'local_youtubesearch') . '">
<button type="submit">' . get_string('search', 'local_youtubesearch') . '</button>
</form>
<div id="youtube-search-results"></div>
';

echo $search_form;

echo $OUTPUT->footer();
18 changes: 18 additions & 0 deletions local/youtubesearch/lang/en/local_youtubesearch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/**
* @package youtubesearch
* @copyright 2024 NYX-EI {@link https://nyx-ei.tech}
* @author NYX-EI <help@nyx-ei.tech>
*/

$string['pluginname'] = 'YouTube Video Search';
$string['search'] = 'Search YouTube';
$string['noresults'] = 'No results found';
$string['preview'] = 'Preview';
$string['addtocourse'] = 'Add to course';
$string['api_key'] = 'YouTube API Key';
$string['api_key_desc'] = 'Enter your YouTube Data API v3 key here';
$string['search_placeholder'] = 'Enter your search query';
$string['video_added'] = 'Video added to the course successfully';
$string['error_adding_video'] = 'An error occurred while adding the video to the course';
63 changes: 63 additions & 0 deletions local/youtubesearch/lib.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

/**
* @package youtubesearch
* @copyright 2024 NYX-EI {@link https://nyx-ei.tech}
* @author NYX-EI <help@nyx-ei.tech>
*/

defined('MOODLE_INTERNAL') || die();

function local_youtubesearch_extend_navigation(global_navigation $navigation) {
global $USER;

if (has_capability('local/youtubesearch:use', context_system::instance(), $USER->id)) {
$node = navigation_node::create(
get_string('pluginname', 'local_youtubesearch'),
new moodle_url('/local/youtubesearch/index.php'),
navigation_node::TYPE_CUSTOM,
null,
'youtubesearch',
new pix_icon('i/search', '')
);
$node->showinflatnavigation = true;

$moremenu = $navigation->find('home', navigation_node::TYPE_CUSTOM);
if ($moremenu) {
$moremenu->add_node($node);
} else {
$navigation->add_node($node);
}
}
}

function local_youtubesearch_youtube_search($query, $max_results = 10) {
$api_key = get_config('local_youtubesearch', 'api_key');
if (empty($api_key)) {
return false;
}

$url = 'https://www.googleapis.com/youtube/v3/search';
$params = [
'part' => 'snippet',
'q' => $query,
'key' => $api_key,
'maxResults' => $max_results,
'type' => 'video'
];

$full_url = $url . '?' . http_build_query($params);
$response = file_get_contents($full_url);

if ($response === false) {
return false;
}

$data = json_decode($response, true);

if (isset($data['items'])) {
return $data['items'];
}

return false;
}
18 changes: 18 additions & 0 deletions local/youtubesearch/search.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/**
* @package youtubesearch
* @copyright 2024 NYX-EI {@link https://nyx-ei.tech}
* @author NYX-EI <help@nyx-ei.tech>
*/

require_once(__DIR__ . '/../../config.php');
require_once($CFG->dirroot . '/local/youtubesearch/lib.php');
require_login();

$query = required_param('q', PARAM_RAW);

$results = local_youtubesearch_youtube_search($query);

header('Content-Type: application/json');
echo json_encode($results);
24 changes: 24 additions & 0 deletions local/youtubesearch/settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

/**
* @package youtubesearch
* @copyright 2024 NYX-EI {@link https://nyx-ei.tech}
* @author NYX-EI <help@nyx-ei.tech>
*/

defined('MOODLE_INTERNAL') || die;

if ($hassiteconfig) { // Vérifiez les permissions
$settings = new admin_settingpage('local_youtubesearch', get_string('pluginname', 'local_youtubesearch'));

// Ajoutez la page de paramètres à la catégorie des plugins locaux
$ADMIN->add('localplugins', $settings);

$settings->add(new admin_setting_configtext(
'local_youtubesearch/api_key',
get_string('api_key', 'local_youtubesearch'),
get_string('api_key_desc', 'local_youtubesearch'),
'',
PARAM_TEXT
));
}
26 changes: 26 additions & 0 deletions local/youtubesearch/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.youtube-search-results {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
margin-top: 1rem;
}

.youtube-video-item {
border: 1px solid #ddd;
padding: 0.5rem;
text-align: center;
}

.youtube-video-item img {
max-width: 100%;
height: auto;
}

.youtube-video-item h3 {
font-size: 1rem;
margin: 0.5rem 0;
}

.youtube-video-item button {
margin: 0.25rem;
}
16 changes: 16 additions & 0 deletions local/youtubesearch/version.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

/**
* Version details
*
* @package youtubesearch
* @author NYX-EI <help@nyx-ei.tech>
*/

defined('MOODLE_INTERNAL') || die();

$plugin->component = 'local_youtubesearch';
$plugin->version = 2024050101;
$plugin->requires = 2024062700;
$plugin->maturity = MATURITY_STABLE;
$plugin->release = '1.1';
Loading

0 comments on commit f03ca0e

Please sign in to comment.