Merge branch 'riadvice-bbb_recording_formats' into 1.11.x

pull/4050/head
Yannick Warnier 5 years ago
commit 56484e1ecd
  1. 23
      app/config/auth.conf.dist.php
  2. 31
      main/admin/course_edit.php
  3. 101
      main/cron/import_csv.php
  4. 38
      main/inc/lib/sessionmanager.lib.php
  5. 4
      main/inc/lib/skill.lib.php
  6. 2
      main/install/configuration.dist.php
  7. 11
      plugin/bbb/README.md
  8. 45
      plugin/bbb/lib/bbb.lib.php
  9. 1114
      plugin/bbb/lib/bbb_api.php
  10. 16
      plugin/bbb/lib/bbb_plugin.class.php
  11. 13
      plugin/bbb/view/listing.tpl
  12. 10
      src/Chamilo/CourseBundle/Component/CourseCopy/CourseSelectForm.php
  13. 4
      src/Chamilo/SkillBundle/Entity/SkillRelCourse.php

@ -4,6 +4,10 @@
/**
* Configuration file for all authentication methods.
* Uncomment and configure only the section(s) you need.
* For MultiURL configuration you can override the configuration
* of every variable by defining the same variable in app/config/configuration.php
* The configuration in app/config/configuration.php will replace
* the configuration in this file.
* @package chamilo.conf.auth
*/
@ -22,6 +26,10 @@
'return_url' => api_get_path(WEB_PATH).'?action=fbconnect',
);*/
$facebookConfig = api_get_configuration_value('facebook_config');
if (!empty($facebookConfig)) {
$facebook_config = $facebookConfig;
}
/**
* Shibboleth
@ -29,6 +37,11 @@
// $shibb_login = ...;
$shibbLogin = api_get_configuration_value('shibb_login');
if (!empty($shibbLogin)) {
$shibb_login = $shibbLogin;
}
/**
* LDAP
*/
@ -116,6 +129,11 @@ $extldap_user_correspondance = array(
) */
);
$ldapUserCorrespondance = api_get_configuration_value('extldap_user_correspondance');
if (!empty($ldapUserCorrespondance)) {
$extldap_user_correspondance = $ldapUserCorrespondance;
}
/**
* Example method to get whether the user is an admin or not. Please implement your logic inside.
*/
@ -146,3 +164,8 @@ $cas = [
// 'fixedServiceURL' => false, // false by default, set to either true or to the service URL string if needed
// sites might also need proxy_settings in configuration.php
];
$casConfig = api_get_configuration_value('cas');
if (!empty($casConfig)) {
$cas = $casConfig;
}

@ -328,6 +328,33 @@ if (api_get_configuration_value('multiple_access_url_show_shared_course_marker')
}
$form->addLabel('URLs', $urlToString);
}
$allowSkillRelItem = api_get_configuration_value('allow_skill_rel_items');
if ($allowSkillRelItem) {
$skillList = [];
$em = Database::getManager();
$items = $em->getRepository('ChamiloSkillBundle:SkillRelCourse')->findBy(
['course' => $courseId, 'session' => null]
);
$form->addHidden('course_id', $courseId);
$form->addHidden('session_id', 0);
/** @var \Chamilo\SkillBundle\Entity\SkillRelCourse $skillRelCourse */
foreach ($items as $skillRelCourse) {
$skillList[$skillRelCourse->getSkill()->getId()] = $skillRelCourse->getSkill()->getName();
}
$form->addSelectAjax(
'skills',
get_lang('Skills'),
$skillList,
[
'url' => api_get_path(WEB_AJAX_PATH).'skill.ajax.php?a=search_skills',
'multiple' => 'multiple',
]
);
$courseInfo['skills'] = array_keys($skillList);
}
$htmlHeadXtra[] = '
<script>
@ -349,6 +376,10 @@ if ($form->validate()) {
$course = $form->getSubmitValues();
$visibility = $course['visibility'];
if ($allowSkillRelItem) {
$result = Skill::saveSkillsToCourseFromForm($form);
}
global $_configuration;
if (isset($_configuration[$urlId]) &&

@ -169,6 +169,10 @@ class ImportCsv
$method = 'importOpenSessions';
}
if ($method == 'importOpensessions') {
$method = 'importOpenSessions';
}
if ($method === 'importSessionsall') {
$method = 'importSessionsUsersCareers';
}
@ -222,6 +226,7 @@ class ImportCsv
'courseinsert-static',
'unsubscribe-static',
'care',
'skillset',
//'careers',
//'careersdiagram',
//'careersresults',
@ -524,6 +529,14 @@ class ImportCsv
''
);
// Course skill set.
CourseManager::create_course_extra_field(
'skillset',
1,
'Skill set',
''
);
CourseManager::create_course_extra_field(
'disable_import_calendar',
13,
@ -1800,6 +1813,81 @@ class ImportCsv
}
}
private function importSkillset(
$file,
$moveFile = true
) {
$this->fixCSVFile($file);
$data = Import::csvToArray($file);
if (!empty($data)) {
$this->logger->addInfo(count($data).' records found.');
$extraFieldValues = new ExtraFieldValue('skill');
$em = Database::getManager();
$repo = $em->getRepository(\Chamilo\CoreBundle\Entity\Skill::class);
$skillSetList = [];
$urlId = api_get_current_access_url_id();
foreach ($data as $row) {
$skill = $repo->findOneBy(['shortCode' => $row['Code']]);
$new = false;
if ($skill === null) {
$new = true;
$skill = new \Chamilo\CoreBundle\Entity\Skill();
$skill
->setShortCode($row['Code'])
->setDescription('')
->setAccessUrlId($urlId)
->setIcon('')
->setStatus(1)
;
}
$skill
->setName($row['Tekst'])
->setUpdatedAt(new DateTime())
;
$em->persist($skill);
$em->flush();
if ($new) {
$skillRelSkill = (new \Chamilo\CoreBundle\Entity\SkillRelSkill())
->setRelationType(0)
->setParentId(0)
->setLevel(0)
->setSkillId($skill->getId())
;
$em->persist($skillRelSkill);
$em->flush();
}
/*
$params = [
'item_id' => $skill->getId(),
'variable' => 'skillset',
'value' => $row['SkillsetID'],
];
$extraFieldValues->save($params);*/
$skillSetList[$row['SkillsetID']][] = $skill->getId();
}
//$courseRelSkills = [];
foreach ($skillSetList as $skillSetId => $skillList) {
$skillList = array_unique($skillList);
if (empty($skillList)) {
continue;
}
$sql = "SELECT id FROM course WHERE code LIKE '%$skillSetId' ";
$result = Database::query($sql);
while ($row = Database::fetch_array($result, 'ASSOC')) {
$courseId = $row['id'];
//$courseRelSkills[$courseId] = $skillList;
Skill::saveSkillsToCourse($skillList, $courseId, null);
}
}
}
}
/**
* @param string $file
* @param bool $moveFile
@ -1820,7 +1908,6 @@ class ImportCsv
foreach ($data as $row) {
$row = $this->cleanCourseRow($row);
$courseId = CourseManager::get_course_id_from_original_id(
$row['extra_'.$this->extraFieldIdNameList['course']],
$this->extraFieldIdNameList['course']
@ -1851,6 +1938,12 @@ class ImportCsv
$row['extra_'.$this->extraFieldIdNameList['course']]
);
CourseManager::update_course_extra_field_value(
$courseInfo['code'],
'skillset',
$row['extra_courseskillset']
);
$this->logger->addInfo("Courses - Course created ".$courseInfo['code']);
} else {
$this->logger->addError("Courses - Can't create course:".$row['title']);
@ -1898,6 +1991,12 @@ class ImportCsv
);
}
CourseManager::update_course_extra_field_value(
$courseInfo['code'],
'skillset',
$row['extra_courseskillset']
);
foreach ($teachers as $teacherId) {
if (isset($groupBackup['tutor'][$teacherId]) &&
isset($groupBackup['tutor'][$teacherId][$courseInfo['code']])

@ -140,13 +140,15 @@ class SessionManager
* @param mixed $coachId If int, this is the session coach id,
* if string, the coach ID will be looked for from the user table
* @param int $sessionCategoryId ID of the session category in which this session is registered
* @param int $visibility Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
* @param int $visibility Visibility after end date (0 = read-only, 1 = invisible, 2 =
* accessible)
* @param bool $fixSessionNameIfExists
* @param string $duration
* @param string $description Optional. The session description
* @param int $showDescription Optional. Whether show the session description
* @param array $extraFields
* @param int $sessionAdminId Optional. If this sessions was created by a session admin, assign it to him
* @param int $sessionAdminId Optional. If this sessions was created by a session admin, assign it
* to him
* @param bool $sendSubscriptionNotification Optional.
* Whether send a mail notification to users being subscribed
* @param int $accessUrlId Optional.
@ -1531,8 +1533,9 @@ class SessionManager
*
* @param string $session_name
* <code>
* $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
* if the course code doest not exist in the DB the same course code will be returned
* $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function
* will return: course3 if the course code doest not exist in the DB the same course
* code will be returned
* </code>
*
* @return string wanted unused code
@ -2558,6 +2561,8 @@ class SessionManager
}
}
$em = Database::getManager();
// Pass through the courses list we want to add to the session
foreach ($courseList as $courseId) {
$courseInfo = api_get_course_info_by_id($courseId);
@ -2709,6 +2714,21 @@ class SessionManager
VALUES ($sessionId, $courseId, 0, 0)";
Database::query($sql);
if (api_get_configuration_value('allow_skill_rel_items')) {
$skillRelCourseRepo = $em->getRepository('ChamiloSkillBundle:SkillRelCourse');
$items = $skillRelCourseRepo->findBy(['course' => $courseId, 'session' => null]);
/** @var \Chamilo\SkillBundle\Entity\SkillRelCourse $item */
foreach ($items as $item) {
$exists = $skillRelCourseRepo->findOneBy(['course' => $courseId, 'session' => $session]);
if (null === $exists) {
$skillRelCourse = clone $item;
$skillRelCourse->setSession($session);
$em->persist($skillRelCourse);
}
}
$em->flush();
}
Event::addEvent(
LOG_SESSION_ADD_COURSE,
LOG_COURSE_ID,
@ -4871,11 +4891,15 @@ class SessionManager
/**
* @param string $file
* @param bool $updateSession true: if the session exists it will be updated.
* false: if session exists a new session will be created adding a counter session1, session2, etc
* false: if session exists a new session will be
* created adding a counter session1, session2, etc
* @param int $defaultUserId
* @param Logger $logger
* @param array $extraFields convert a file row to an extra field. Example in CSV file there's a SessionID
* then it will converted to extra_external_session_id if you set: array('SessionId' => 'extra_external_session_id')
* @param array $extraFields convert a file row to an extra field. Example in
* CSV file there's a SessionID then it will
* converted to extra_external_session_id if you
* set: array('SessionId' =>
* 'extra_external_session_id')
* @param string $extraFieldId
* @param int $daysCoachAccessBeforeBeginning
* @param int $daysCoachAccessAfterBeginning

@ -2869,7 +2869,7 @@ class Skill extends Model
{
$skills = (array) $form->getSubmitValue('skills');
$courseId = (int) $form->getSubmitValue('course_id');
$sessionId = $form->getSubmitValue('session_id');
$sessionId = (int) $form->getSubmitValue('session_id');
return self::saveSkillsToCourse($skills, $courseId, $sessionId);
}
@ -2879,8 +2879,6 @@ class Skill extends Model
* @param int $courseId
* @param int $sessionId
*
* @throws \Doctrine\ORM\OptimisticLockException
*
* @return bool
*/
public static function saveSkillsToCourse($skills, $courseId, $sessionId)

@ -906,7 +906,7 @@ ALTER TABLE skill_rel_item_rel_user ADD CONSTRAINT FK_D1133E0DA76ED395 FOREIGN K
ALTER TABLE skill_rel_item ADD CONSTRAINT FK_EB5B2A0D5585C142 FOREIGN KEY (skill_id) REFERENCES skill (id);
ALTER TABLE skill_rel_item_rel_user ADD result_id INT DEFAULT NULL;
CREATE TABLE skill_rel_course (id INT AUTO_INCREMENT NOT NULL, skill_id INT DEFAULT NULL, c_id INT NOT NULL, session_id INT NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX IDX_E7CEC7FA5585C142 (skill_id), INDEX IDX_E7CEC7FA91D79BD3 (c_id), INDEX IDX_E7CEC7FA613FECDF (session_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE skill_rel_course (id INT AUTO_INCREMENT NOT NULL, skill_id INT DEFAULT NULL, c_id INT NOT NULL, session_id INT, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX IDX_E7CEC7FA5585C142 (skill_id), INDEX IDX_E7CEC7FA91D79BD3 (c_id), INDEX IDX_E7CEC7FA613FECDF (session_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE skill_rel_course ADD CONSTRAINT FK_E7CEC7FA5585C142 FOREIGN KEY (skill_id) REFERENCES skill (id);
ALTER TABLE skill_rel_course ADD CONSTRAINT FK_E7CEC7FA91D79BD3 FOREIGN KEY (c_id) REFERENCES course (id);
ALTER TABLE skill_rel_course ADD CONSTRAINT FK_E7CEC7FA613FECDF FOREIGN KEY (session_id) REFERENCES session (id);

@ -72,6 +72,17 @@ ALTER TABLE plugin_bbb_room DROP COLUMN interface;
ALTER TABLE plugin_bbb_meeting DROP COLUMN interface;
```
For version 2.10 (Handles multiple recording formats - Check https://github.com/chamilo/chamilo-lms/issues/3703)
```sql
CREATE TABLE plugin_bbb_meeting_format (
id int unsigned not null PRIMARY KEY AUTO_INCREMENT,
meeting_id int unsigned not null,
format_type varchar(255) not null,
resource_url text not null
)
```
## Improve access tracking in BBB
You need to configure the cron using the *cron_close_meeting.php* file.

@ -1041,18 +1041,23 @@ class bbb
continue;
}
if (!empty($record['playbackFormatUrl'])) {
if (!empty($record['playbackFormat'])) {
$this->updateMeetingVideoUrl($meetingDB['id'], $record['playbackFormatUrl']);
}
}
}
if (isset($record['playbackFormatUrl']) && !empty($record['playbackFormatUrl'])) {
$recordLink = Display::url(
$this->plugin->get_lang('ViewRecord'),
$record['playbackFormatUrl'],
['target' => '_blank', 'class' => 'btn btn-default']
);
if (isset($record['playbackFormat']) && !empty($record['playbackFormat'])) {
$recordLink = [];
foreach ($record['playbackFormat'] as $format) {
$this->insertMeetingFormat(intval($meetingDB['id']), $format->type->__toString(), $format->url->__toString());
$recordLink['record'][] = 1;
$recordLink[] = Display::url(
$this->plugin->get_lang($format->type->__toString()),
$format->url->__toString(),
['target' => '_blank', 'class' => 'btn btn-default']
);
}
} else {
$recordLink = $this->plugin->get_lang('NoRecording');
}
@ -1072,6 +1077,7 @@ class bbb
$isAdminReport
);
$item['show_links'] = $recordLink;
$item['record'] = true;
} else {
$actionLinks = $this->getActionLinks(
$meetingDB,
@ -1081,6 +1087,7 @@ class bbb
);
$item['show_links'] = $this->plugin->get_lang('NoRecording');
$item['record'] = false;
}
$item['action_links'] = implode(PHP_EOL, $actionLinks);
@ -1244,6 +1251,30 @@ class bbb
);
}
/**
* @param int $meetingId
* @param string $formatType
* @param string $resourceUrl
*
* @return bool|int
*/
public function insertMeetingFormat(int $meetingId, string $formatType, string $resourceUrl)
{
$em = Database::getManager();
$sm = $em->getConnection()->getSchemaManager();
if ($sm->tablesExist('plugin_bbb_meeting_format')) {
return Database::insert(
'plugin_bbb_meeting_format',
[
'format_type' => $formatType,
'resource_url' => $resourceUrl,
'meeting_id' => $meetingId
]
);
}
}
/**
* Force the course, session and/or group IDs
*

File diff suppressed because it is too large Load Diff

@ -45,8 +45,8 @@ class BBBPlugin extends Plugin
protected function __construct()
{
parent::__construct(
'2.9',
'Julio Montoya, Yannick Warnier, Angel Fernando Quiroz Campos, Jose Angel Ruiz',
'2.10',
'Julio Montoya, Yannick Warnier, Angel Fernando Quiroz Campos, Jose Angel Ruiz, Ghazi Triki, Adnen Manssouri',
[
'tool_enable' => 'boolean',
'host' => 'text',
@ -230,6 +230,15 @@ class BBBPlugin extends Plugin
]
);
Database::query(
"CREATE TABLE plugin_bbb_meeting_format (
id int unsigned not null PRIMARY KEY AUTO_INCREMENT,
meeting_id int unsigned not null,
format_type varchar(255) not null,
resource_url text not null
);"
);
// Copy icons into the main/img/icons folder
$iconName = 'bigbluebutton';
$iconsList = [
@ -313,6 +322,9 @@ class BBBPlugin extends Plugin
$sql = "DELETE FROM $t_tool WHERE name = 'bbb' AND c_id != 0";
Database::query($sql);
if ($sm->tablesExist('plugin_bbb_meeting_format')) {
Database::query('DROP TABLE IF EXISTS plugin_bbb_meeting_format');
}
if ($sm->tablesExist('plugin_bbb_room')) {
Database::query('DROP TABLE IF EXISTS plugin_bbb_room');
}

@ -84,12 +84,17 @@
{% endif %}
</td>
<td>
{% if meeting.record == 1 %}
{% if meeting.show_links.record %}
{# Record list #}
{{ meeting.show_links }}
{% else %}
{{ 'NoRecording'|get_plugin_lang('BBBPlugin') }}
{% for link in meeting.show_links %}
{% if link is not iterable %}
{{ link }}
{% endif %}
{% endfor %}
{% else %}
{{ 'NoRecording'|get_plugin_lang('BBBPlugin') }}
{% endif %}
</td>
{% if allow_to_edit %}
<td>

@ -110,12 +110,15 @@ class CourseSelectForm
function checkLearnPath(message){
d = document.course_select_form;
var backup = (typeof d.destination_course === 'undefined');
for (i = 0; i < d.elements.length; i++) {
if (d.elements[i].type == "checkbox") {
var name = d.elements[i].attributes.getNamedItem('name').nodeValue;
if( name.indexOf('learnpath') > 0 || name.indexOf('quiz') > 0){
if(d.elements[i].checked){
//setCheckbox('document',true);
if (!backup) {
setCheckbox('document', true);
}
alert(message);
break;
}
@ -744,12 +747,15 @@ class CourseSelectForm
}
function checkLearnPath(message){
d = document.course_select_form;
var backup = (typeof d.destination_course === 'undefined');
for (i = 0; i < d.elements.length; i++) {
if (d.elements[i].type == "checkbox") {
var name = d.elements[i].attributes.getNamedItem('name').nodeValue;
if( name.indexOf('learnpath') > 0 || name.indexOf('quiz') > 0){
if(d.elements[i].checked){
//setCheckbox('document',true);
if (!backup) {
setCheckbox('document', true);
}
alert(message);
break;
}

@ -10,8 +10,6 @@ use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* SkillRelCourse.
*
* @ORM\Table(name="skill_rel_course")
* ORM\Entity // uncomment if api_get_configuration_value('allow_skill_rel_items')
*/
@ -43,7 +41,7 @@ class SkillRelCourse
/**
* @var Session
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\Session", inversedBy="skills", cascade={"persist"})
* @ORM\JoinColumn(name="session_id", referencedColumnName="id", nullable=false)
* @ORM\JoinColumn(name="session_id", referencedColumnName="id")
*/
protected $session;

Loading…
Cancel
Save