Merge branch '1.11.x' of github.com:chamilo/chamilo-lms into 1.11.x

pull/2585/head
Yannick Warnier 7 years ago
commit f0ec20364e
  1. 19
      app/Resources/public/assets/jqueryui-touch-punch/.bower.json
  2. 41
      app/Resources/public/assets/jqueryui-touch-punch/README.md
  3. 10
      app/Resources/public/assets/jqueryui-touch-punch/bower.json
  4. 180
      app/Resources/public/assets/jqueryui-touch-punch/jquery.ui.touch-punch.js
  5. 11
      app/Resources/public/assets/jqueryui-touch-punch/jquery.ui.touch-punch.min.js
  6. 15
      app/Resources/public/css/base.css
  7. 3
      bower.json
  8. 1
      main/coursecopy/create_backup.php
  9. 15
      main/inc/lib/course.lib.php
  10. 49
      main/inc/lib/exercise.lib.php
  11. 4
      main/inc/lib/fixlinks.js
  12. 37
      main/inc/lib/hook/HookCreateCourse.php
  13. 23
      main/inc/lib/hook/interfaces/HookCreateCourseEventInterface.php
  14. 21
      main/inc/lib/hook/interfaces/HookCreateCourseObserverInterface.php
  15. 2
      main/inc/lib/javascript/asciimath/ASCIIMathML.js
  16. 4
      main/inc/lib/javascript/svgedit/extensions/imagelib/groups.php
  17. 8
      main/inc/lib/javascript/svgedit/extensions/imagelib/index.php
  18. 3
      main/inc/lib/plugin.class.php
  19. 6
      main/inc/lib/sortable_table.class.php
  20. 1
      main/inc/lib/template.lib.php
  21. 2
      main/inc/lib/usergroup.lib.php
  22. 4
      main/inc/lib/userportal.lib.php
  23. 2
      main/install/configuration.dist.php
  24. 2
      main/lp/scorm.class.php
  25. 4
      main/lp/scorm_api.php
  26. 8
      main/mySpace/myStudents.php
  27. 2
      main/portfolio/edit_item.php
  28. 4
      main/portfolio/index.php
  29. 4
      main/survey/create_new_survey.php
  30. 3
      main/survey/survey.lib.php
  31. 6
      main/template/default/user_portal/grid_courses_without_category.tpl
  32. 6
      main/template/default/user_portal/grid_session.tpl
  33. 23
      plugin/buycourses/lang/english.php
  34. 27
      plugin/buycourses/lang/french.php
  35. 6
      plugin/buycourses/src/sales_report.php
  36. 1
      plugin/customcertificate/lang/english.php
  37. 1
      plugin/customcertificate/lang/spanish.php
  38. 16
      plugin/customcertificate/src/index.php
  39. 204
      plugin/customcertificate/src/print_certificate.php
  40. 13
      plugin/olpc_peru_filter/lib/olpc_peru_filter_plugin.class.php
  41. 2
      src/Chamilo/CoreBundle/Entity/Portfolio.php
  42. 21
      src/Chamilo/CourseBundle/Component/CourseCopy/CourseBuilder.php
  43. 1
      src/Chamilo/CourseBundle/Component/CourseCopy/CourseRestorer.php
  44. 14
      src/Chamilo/CourseBundle/Component/CourseCopy/CourseSelectForm.php
  45. 8
      tests/behat/features/bootstrap/FeatureContext.php
  46. 4
      tests/behat/features/toolLp.feature

@ -0,0 +1,19 @@
{
"name": "jqueryui-touch-punch",
"main": "jquery.ui.touch-punch.min.js",
"ignore": [],
"dependencies": {
"jquery": ">=1.6",
"jquery-ui": ">=1.8"
},
"homepage": "https://github.com/furf/jquery-ui-touch-punch",
"_release": "4bc0091452",
"_resolution": {
"type": "branch",
"branch": "master",
"commit": "4bc009145202d9c7483ba85f3a236a8f3470354d"
},
"_source": "https://github.com/furf/jquery-ui-touch-punch.git",
"_target": "*",
"_originalSource": "jqueryui-touch-punch"
}

@ -0,0 +1,41 @@
# jQuery UI Touch Punch
## Touch Event Support for jQuery UI
> **jQuery UI Touch Punch is a small hack that enables the use of touch events on sites using the jQuery UI user interface library.**
_[Visit the official Touch Punch website](http://touchpunch.furf.com)._
Currently, [jQuery UI](http://jqueryui.com/) user interface library does not support the use of touch events in their widgets and interactions. This means that the slick UI you designed and tested in your desktop browser will fail on most, if not all, touch-enabled mobile devices, because jQuery UI listens to mouse events—mouseover, mousemove and mouseout—not touch events—touchstart, touchmove and touchend.
That's where jQuery UI Touch Punch comes in. Touch Punch works by using [simulated events](https://developer.mozilla.org/en/DOM/document.createEvent) to map [touch events](http://www.html5rocks.com/en/mobile/touch/) to their mouse event analogs. Simply include the script on your page and your touch events will be turned into their corresponding mouse events to which jQuery UI will respond as expected.
As I said, Touch Punch is a hack. It [duck punches](http://en.wikipedia.org/wiki/Monkey_patch) some of jQuery UI's core functionality to handle the mapping of touch events. Touch Punch works with all basic implementations of jQuery UI's interactions and widgets. However, you may find more complex cases where Touch Punch fails. If so, scroll down to learn how you can file and/or fix issues.
This code is dual licensed under the MIT or GPL Version 2 licenses and is therefore free to use, modify and/or distribute, but if you include Touch Punch in other software packages or plugins, please include an attribution to the original software and a link to [this Touch Punch website](http://touchpunch.furf.com/).
## Using Touch Punch is as easy as 1, 2…
Just follow these simple steps to enable touch events in your jQuery UI app:
1. Include jQuery and jQuery UI on your page.
```html
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.8.17/jquery-ui.min.js"></script>
```
2. Include Touch Punch after jQuery UI and before its first use.
Please note that if you are using jQuery UI's components, Touch Punch must be included after jquery.ui.mouse.js, as Touch Punch modifies its behavior.
```html
<script src="jquery.ui.touch-punch.min.js"></script>
```
3. There is no 3. Just use jQuery UI as expected and watch it work at the touch of a finger.
```html
<script>$('#widget').draggable();</script>
```
_Tested on iPad, iPhone, Android and other touch-enabled mobile devices._

@ -0,0 +1,10 @@
{
"name": "jqueryui-touch-punch",
"version": "0.2.3",
"main": "jquery.ui.touch-punch.min.js",
"ignore": [],
"dependencies": {
"jquery": ">=1.6",
"jquery-ui": ">=1.8"
}
}

@ -0,0 +1,180 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
(function ($) {
// Detect touch support
$.support.touch = 'ontouchend' in document;
// Ignore browsers without touch support
if (!$.support.touch) {
return;
}
var mouseProto = $.ui.mouse.prototype,
_mouseInit = mouseProto._mouseInit,
_mouseDestroy = mouseProto._mouseDestroy,
touchHandled;
/**
* Simulate a mouse event based on a corresponding touch event
* @param {Object} event A touch event
* @param {String} simulatedType The corresponding mouse event
*/
function simulateMouseEvent (event, simulatedType) {
// Ignore multi-touch events
if (event.originalEvent.touches.length > 1) {
return;
}
event.preventDefault();
var touch = event.originalEvent.changedTouches[0],
simulatedEvent = document.createEvent('MouseEvents');
// Initialize the simulated mouse event using the touch event's coordinates
simulatedEvent.initMouseEvent(
simulatedType, // type
true, // bubbles
true, // cancelable
window, // view
1, // detail
touch.screenX, // screenX
touch.screenY, // screenY
touch.clientX, // clientX
touch.clientY, // clientY
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
0, // button
null // relatedTarget
);
// Dispatch the simulated event to the target element
event.target.dispatchEvent(simulatedEvent);
}
/**
* Handle the jQuery UI widget's touchstart events
* @param {Object} event The widget element's touchstart event
*/
mouseProto._touchStart = function (event) {
var self = this;
// Ignore the event if another widget is already being handled
if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
return;
}
// Set the flag to prevent other widgets from inheriting the touch event
touchHandled = true;
// Track movement to determine if interaction was a click
self._touchMoved = false;
// Simulate the mouseover event
simulateMouseEvent(event, 'mouseover');
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
// Simulate the mousedown event
simulateMouseEvent(event, 'mousedown');
};
/**
* Handle the jQuery UI widget's touchmove events
* @param {Object} event The document's touchmove event
*/
mouseProto._touchMove = function (event) {
// Ignore event if not handled
if (!touchHandled) {
return;
}
// Interaction was not a click
this._touchMoved = true;
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
};
/**
* Handle the jQuery UI widget's touchend events
* @param {Object} event The document's touchend event
*/
mouseProto._touchEnd = function (event) {
// Ignore event if not handled
if (!touchHandled) {
return;
}
// Simulate the mouseup event
simulateMouseEvent(event, 'mouseup');
// Simulate the mouseout event
simulateMouseEvent(event, 'mouseout');
// If the touch interaction did not move, it should trigger a click
if (!this._touchMoved) {
// Simulate the click event
simulateMouseEvent(event, 'click');
}
// Unset the flag to allow other widgets to inherit the touch event
touchHandled = false;
};
/**
* A duck punch of the $.ui.mouse _mouseInit method to support touch events.
* This method extends the widget with bound touch event handlers that
* translate touch events to mouse events and pass them to the widget's
* original mouse event handling methods.
*/
mouseProto._mouseInit = function () {
var self = this;
// Delegate the touch handlers to the widget's element
self.element.bind({
touchstart: $.proxy(self, '_touchStart'),
touchmove: $.proxy(self, '_touchMove'),
touchend: $.proxy(self, '_touchEnd')
});
// Call the original $.ui.mouse init method
_mouseInit.call(self);
};
/**
* Remove the touch event handlers
*/
mouseProto._mouseDestroy = function () {
var self = this;
// Delegate the touch handlers to the widget's element
self.element.unbind({
touchstart: $.proxy(self, '_touchStart'),
touchmove: $.proxy(self, '_touchMove'),
touchend: $.proxy(self, '_touchEnd')
});
// Call the original $.ui.mouse destroy method
_mouseDestroy.call(self);
};
})(jQuery);

@ -0,0 +1,11 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);

@ -5897,12 +5897,15 @@ div#chat-remote-video video {
.grid-courses .items .code-title {
font-size: 10px;
font-weight: normal;
font-weight: bold;
padding-top: 8px;
color: #666;
}
.toolbar-edit {
display: inline-block;
width: 100%;
margin-top: 10px;
}
.bar-progress {
@ -5939,10 +5942,6 @@ div#chat-remote-video video {
font-size: 14px;
}
.grid-courses .items.my-courses .block-title {
margin: 10px;
}
.grid-courses .items.items-courses {
padding-bottom: 10px;
box-shadow: 2px 4px 15px 0 rgba(46, 61, 73, .1);
@ -5973,6 +5972,7 @@ div#chat-remote-video video {
padding: 0;
font-weight: bold;
margin: 0;
font-size: 14px;
}
.grid-courses .items .toolbar > div {
@ -6100,7 +6100,8 @@ div#chat-remote-video video {
}
.grid-courses .items .description {
padding: 5px 10px 15px;
padding: 5px 10px 5px;
min-height: 125px;
}
.grid-courses .items .description .text {
@ -6136,7 +6137,7 @@ div#chat-remote-video video {
/*---- */
.grid-courses .items .block-author {
display: flex;
margin: 5px 0 10px;
margin: 5px 0 5px;
}
.grid-courses .items .block-author img {

@ -33,7 +33,8 @@
"qtip2": "*",
"js-cookie": "2.1.*",
"flag-icon-css": "*",
"jquery.easy-pie-chart": "^2.1.6"
"jquery.easy-pie-chart": "^2.1.6",
"jqueryui-touch-punch": "*"
},
"resolutions": {
"jquery": "2.1.4"

@ -115,4 +115,3 @@ if (Security::check_token('post') &&
}
Display::display_footer();

@ -41,6 +41,9 @@ class CourseManager
public static function create_course($params, $authorId = 0)
{
global $_configuration;
$hook = HookCreateCourse::create();
// Check portal limits
$access_url_id = 1;
if (api_get_multiple_access_url()) {
@ -98,6 +101,11 @@ class CourseManager
$course_id = AddCourse::register_course($params);
$course_info = api_get_course_info_by_id($course_id);
if ($hook) {
$hook->setEventData(['course_info' => $course_info]);
$hook->notifyCreateCourse(HOOK_EVENT_TYPE_POST);
}
if (!empty($course_info)) {
self::fillCourse($course_info, $params, $authorId);
@ -4310,7 +4318,7 @@ class CourseManager
if ($userInCourseStatus == COURSEMANAGER || $sessionCourseAvailable) {
$session_url = $course_info['course_public_url'].'?id_session='.$course_info['id_session'];
$session_title = '<a href="'.$session_url.'">'.$course_info['name'].'</a>'.$notifications;
$session_title = '<a title="'.$course_info['name'].'" href="'.$session_url.'">'.$course_info['name'].'</a>'.$notifications;
} else {
$session_title = $course_info['name'];
}
@ -4345,6 +4353,7 @@ class CourseManager
$params['image'] = $image;
$params['link'] = $session_url;
$params['title'] = $session_title;
$params['name'] = $course_info['name'];
$params['edit_actions'] = '';
$params['document'] = '';
$params['category'] = $course_info['categoryName'];
@ -4385,7 +4394,9 @@ class CourseManager
$special = isset($course['special_course']) ? true : false;
$params['title'] = $session_title;
$params['special'] = $special;
$params['code'] = $course_info['visual_code'];
if (api_get_setting('display_coursecode_in_courselist') === 'true') {
$params['visual_code'] = '('.$course_info['visual_code'].')';
}
$params['extra'] = '';
$html = $params;

@ -2229,13 +2229,11 @@ HOTSPOT;
$results[$i]['username'],
$dt
).'\')) return false;">';
$delete_link .= Display:: return_icon(
$delete_link .= Display::return_icon(
'delete.png',
addslashes(get_lang('Delete'))
).'</a>';
//$delete_link = utf8_encode($delete_link);
if (api_is_drh() && !api_is_platform_admin()) {
$delete_link = null;
}
@ -2400,18 +2398,30 @@ HOTSPOT;
$roundValues
);
$results[$i]['only_score'] = $scoreDisplay->format_score(
$my_res,
false,
$decimalSeparator,
$thousandSeparator
);
$results[$i]['total'] = $scoreDisplay->format_score(
$my_total,
false,
$decimalSeparator,
$thousandSeparator
);
if ($roundValues) {
$onlyScore = ceil($my_res);
} else {
$onlyScore = $scoreDisplay->format_score(
$my_res,
false,
$decimalSeparator,
$thousandSeparator
);
}
$results[$i]['only_score'] = $onlyScore;
if ($roundValues) {
$onlyTotal = ceil($my_total);
} else {
$onlyTotal = $scoreDisplay->format_score(
$my_total,
false,
$decimalSeparator,
$thousandSeparator
);
}
$results[$i]['total'] = $onlyTotal;
$results[$i]['lp'] = $lp_name;
$results[$i]['actions'] = $actions;
$listInfo[] = $results[$i];
@ -2493,7 +2503,7 @@ HOTSPOT;
* @param bool $hidePercentageSign hide "%" sign
* @param string $decimalSeparator
* @param string $thousandSeparator
* @param bool $roundValues This option rounds the float values into a int using ceil()
* @param bool $roundValues This option rounds the float values into a int using ceil()
*
* @return string an html with the score modified
*/
@ -2527,13 +2537,14 @@ HOTSPOT;
}
$percentage = (100 * $score) / ($weight != 0 ? $weight : 1);
// Formats values
$percentage = float_format($percentage, 1, $decimalSeparator, $thousandSeparator);
if ($roundValues) {
// Formats values
$percentage = ceil($percentage);
$score = ceil($score);
$weight = ceil($weight);
} else {
// Formats values
$percentage = float_format($percentage, 1, $decimalSeparator, $thousandSeparator);
$score = float_format($score, 1, $decimalSeparator, $thousandSeparator);
$weight = float_format($weight, 1, $decimalSeparator, $thousandSeparator);
}

@ -42,7 +42,7 @@ $(document).ready(function() {
var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
var uniqid = randLetter + Date.now();
var openerId = uniqid +'_opener';
var link = '<a id="'+openerId+'" class="generated" href="#">Open website.<img src="'+iconPath+'link-external.png "/></a>';
var link = '<a id="'+openerId+'" class="generated" href="#">Open website.<img width="16px" src="'+iconPath+'link-external.png "/></a>';
var embed = $(this);
var height = embed.attr('height');
var width = embed.attr('width');
@ -109,7 +109,7 @@ $(document).ready(function() {
src = url+'&type=link&src='+src;
src = src.replace('https', 'http');
$(this).attr('href', src);
var myAnchor = $('<a><img src="'+iconPath+'link-external.png "/></a>').attr("href", src).attr('target', '_blank').attr('class', 'generated');
var myAnchor = $('<a><img width="16px" src="'+iconPath+'link-external.png "/></a>').attr("href", src).attr('target', '_blank').attr('class', 'generated');
$(this).after(myAnchor);
$(this).after('-');
}

@ -0,0 +1,37 @@
<?php
/* For licensing terms, see /license.txt */
/**
* Class HookCreateCourse.
*/
class HookCreateCourse extends HookEvent implements HookCreateCourseEventInterface
{
/**
* HookCreateCourse constructor.
*
* @throws Exception
*/
protected function __construct()
{
parent::__construct('HookCreateCourse');
}
/**
* Update all the observers.
*
* @param int $type
*
* @return int
*/
public function notifyCreateCourse($type)
{
$this->eventData['type'] = $type;
/** @var HookCreateCourseObserverInterface $observer */
foreach ($this->observers as $observer) {
$observer->hookCreateCourse($this);
}
return 1;
}
}

@ -0,0 +1,23 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This file contains all Hook interfaces and their relation.
* They are used for Hook classes.
*
* @package chamilo.library.hook
*/
/**
* Interface HookCreateUserEventInterface.
*/
interface HookCreateCourseEventInterface extends HookEventInterface
{
/**
* Update all the observers.
*
* @param int $type
*
* @return int
*/
public function notifyCreateCourse($type);
}

@ -0,0 +1,21 @@
<?php
/* For licensing terms, see /license.txt */
/**
* This file contains all Hook interfaces and their relation.
* They are used for Hook classes.
*
* @package chamilo.library.hook
*/
/**
* Interface CreateUserHookInterface.
*/
interface HookCreateCourseObserverInterface extends HookObserverInterface
{
/**
* @param HookCreateCourseEventInterface $hook
*
* @return int
*/
public function hookCreateCourse(HookCreateCourseEventInterface $hook);
}

@ -89,7 +89,7 @@ var AMTcgiloc = "//chart.googleapis.com/chart?cht=tx&chs=1x0&chl=";
var AScgiloc = '//www.imathas.com/imathas/filter/graph/svgimg.php'; //path to CGI script
//for editor graphs IMG fallback
var mathcolor = "blue"; // change it to "" (to inherit) or another color
var mathcolor = "black"; // change it to "" (to inherit) or another color
// Modified by Ivan Tcholakov, 01-JUL-2010.
//var mathfontsize = "1em"; // change to e.g. 1.2em for larger math
var mathfontsize = "1.2em";

@ -33,15 +33,17 @@ $docs_and_folders = DocumentManager::getAllDocumentData(
//get all group filenames
$array_to_search = !empty($docs_and_folders) ? $docs_and_folders : [];
$all_files = [];
if (count($array_to_search) > 0) {
while (list($key) = each($array_to_search)) {
foreach ($array_to_search as $key => $value) {
$all_files[] = basename($array_to_search[$key]['path']);
}
}
//get all svg and png group files
$accepted_extensions = array('.svg', '.png');
$png_svg_files = [];
if (is_array($all_files) && count($all_files) > 0) {
foreach ($all_files as & $file) {

@ -26,15 +26,17 @@ $docs_and_folders = DocumentManager::getAllDocumentData(
//get all filenames
$array_to_search = !empty($docs_and_folders) ? $docs_and_folders : [];
$all_files = [];
if (count($array_to_search) > 0) {
while (list($key) = each($array_to_search)) {
$all_files[] = basename($array_to_search[$key]['path']);
}
foreach ($array_to_search as $key => $value) {
$all_files[] = basename($array_to_search[$key]['path']);
}
}
//get all svg and png files
$accepted_extensions = array('.svg', '.png');
$png_svg_files = [];
if (is_array($all_files) && count($all_files) > 0) {
foreach ($all_files as & $file) {

@ -684,6 +684,7 @@ class Plugin
}
}
$currentUrlId = api_get_current_access_url_id();
$attributes = [
'variable' => 'show_tabs',
'subkey' => $subkey,
@ -693,7 +694,7 @@ class Plugin
'title' => $tabName,
'comment' => $url,
'subkeytext' => $subkeytext,
'access_url' => 1,
'access_url' => $currentUrlId,
'access_url_changeable' => 1,
'access_url_locked' => 0,
];

@ -675,7 +675,11 @@ class SortableTable extends HTML_Table
$result[] = '<input type="hidden" name="'.$key.'" value="'.$value.'"/>';
}
$result[] = '<select name="'.$this->param_prefix.'per_page" onchange="javascript: this.form.submit();">';
for ($nr = 10; $nr <= min(50, $total_number_of_items); $nr += 10) {
$list = [10, 20, 50, 100, 500, 1000];
foreach ($list as $nr) {
if ($total_number_of_items <= $nr) {
break;
}
$result[] = '<option value="'.$nr.'" '.($nr == $this->per_page ? 'selected="selected"' : '').'>'.$nr.'</option>';
}
// @todo no limits

@ -748,6 +748,7 @@ class Template
'jquery/dist/jquery.min.js',
'bootstrap/dist/js/bootstrap.min.js',
'jquery-ui/jquery-ui.min.js',
'jqueryui-touch-punch/jquery.ui.touch-punch.min.js',
'moment/min/moment-with-locales.js',
'bootstrap-daterangepicker/daterangepicker.js',
'jquery-timeago/jquery.timeago.js',

@ -620,7 +620,7 @@ class UserGroup extends Model
if ($this->useMultipleUrl) {
$urlId = api_get_current_access_url_id();
$from = $this->usergroup_rel_user_table." u
INNER JOIN {$this->access_url_rel_usergroup} a ON (a.usergroup_id AND u.usergroup_id)";
INNER JOIN {$this->access_url_rel_usergroup} a ON (a.usergroup_id = u.usergroup_id)";
$where = ['where' => ['user_id = ? AND access_url_id = ? ' => [$userId, $urlId]]];
} else {
$from = $this->usergroup_rel_user_table." u ";

@ -547,7 +547,7 @@ class IndexManager
$courses_list_string .= '<a href="'.$web_course_path.$course['directory'].'/">'.$course['title'].'</a><br />';
$course_details = [];
if (api_get_setting('display_coursecode_in_courselist') === 'true') {
$course_details[] = $course['visual_code'];
$course_details[] = '('.$course['visual_code'].')';
}
if (api_get_setting('display_teacher_in_courselist') === 'true') {
$course_details[] = CourseManager::getTeacherListFromCourseCodeToString($course['code']);
@ -592,7 +592,7 @@ class IndexManager
}
$course_details = [];
if (api_get_setting('display_coursecode_in_courselist') == 'true') {
$course_details[] = $course['visual_code'];
$course_details[] = '('.$course['visual_code'].')';
}
if (api_get_setting('display_teacher_in_courselist') === 'true') {
if (!empty($course['tutor_name'])) {

@ -820,7 +820,7 @@ CREATE TABLE portfolio_category (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED1062A76ED395 FOREIGN KEY (user_id) REFERENCES user (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED106291D79BD3 FOREIGN KEY (c_id) REFERENCES course (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED1062613FECDF FOREIGN KEY (session_id) REFERENCES session (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED106212469DE2 FOREIGN KEY (category_id) REFERENCES portfolio_category (id);
ALTER TABLE portfolio ADD CONSTRAINT FK_A9ED106212469DE2 FOREIGN KEY (category_id) REFERENCES portfolio_category (id) ON DELETE SET NULL;
ALTER TABLE portfolio_category ADD CONSTRAINT FK_7AC64359A76ED395 FOREIGN KEY (user_id) REFERENCES user (id);
INSERT INTO settings_current(variable, subkey, type, category, selected_value, title, comment, scope, subkeytext, access_url_changeable) VALUES('course_create_active_tools','portfolio','checkbox','Tools','true','CourseCreateActiveToolsTitle','CourseCreateActiveToolsComment',NULL,'Portfolio', 0);
*/

@ -289,7 +289,7 @@ class scorm extends learnpath
'$iFrameHolder.html(iFrameTag);',
];
$replace = [
'iFrameTag = \'<a target ="_blank" href="'.$proxyPath.'?type=link&src=\'+ pageSrc + \'">Open website. <img src="'.api_get_path(WEB_CODE_PATH).'img/link-external.png"></a>\'; $iFrameHolder.html(iFrameTag); ',
'iFrameTag = \'<a target ="_blank" href="'.$proxyPath.'?type=link&src=\'+ pageSrc + \'">Open website. <img width="16px" src="'.Display::returnIconPath('link-external.png').'"></a>\'; $iFrameHolder.html(iFrameTag); ',
];
$content = str_replace($find, $replace, $content);
file_put_contents($framePath, $content);

@ -2294,7 +2294,7 @@ function attach_glossary_into_scorm(type) {
var randLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
var uniqid = randLetter + Date.now();
var openerId = uniqid +'_opener';
var link = '<a id="'+openerId+'" class="generated" href="#">Open website <img src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>';
var link = '<a id="'+openerId+'" class="generated" href="#">Open website <img width="16px" src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>';
var embed = $(this);
var height = embed.attr('height');
var width = embed.attr('width');
@ -2359,7 +2359,7 @@ function attach_glossary_into_scorm(type) {
src = url+'&type=link&src='+src;
src = src.replace('https', 'http');
$(this).attr('href', src);
var myAnchor = $('<a><img src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>').attr("href", src).attr('target', '_blank').attr('class', 'generated');
var myAnchor = $('<a><img width="16px" src="<?php echo Display::returnIconPath('link-external.png'); ?>"/></a>').attr("href", src).attr('target', '_blank').attr('class', 'generated');
$(this).after(myAnchor);
$(this).after('-');
}

@ -735,7 +735,7 @@ $userGroups = $userGroupManager->getNameListByUser(
<td align="right">
<?php
echo get_lang('Progress').' ';
Display::display_icon(
Display::display_icon(
'info3.gif',
get_lang('ScormAndLPProgressTotalAverage'),
['align' => 'absmiddle', 'hspace' => '3px']
@ -747,7 +747,7 @@ $userGroups = $userGroupManager->getNameListByUser(
<td align="right">
<?php
echo get_lang('Score').' ';
Display::display_icon(
Display::display_icon(
'info3.gif',
get_lang('ScormAndLPTestTotalAverage'),
['align' => 'absmiddle', 'hspace' => '3px']
@ -799,7 +799,7 @@ $userGroups = $userGroupManager->getNameListByUser(
</tbody>
</table>
<?php if (!empty($userGroups)) {
?>
?>
<table class="table table-striped table-hover">
<thead>
<tr>
@ -817,7 +817,7 @@ $userGroups = $userGroupManager->getNameListByUser(
</tbody>
</table>
<?php
} ?>
} ?>
</div>
</div>
<?php

@ -39,7 +39,7 @@ if ($form->validate()) {
$em->flush();
Display::addFlash(
Display::return_message(get_lang('Updated'), 'success')
Display::return_message(get_lang('ItemUpdated'), 'success')
);
header("Location: $baseUrl");

@ -133,7 +133,7 @@ switch ($action) {
$em->flush();
Display::addFlash(
Display::return_message(get_lang('PortfolioItemDeleted'), 'success')
Display::return_message(get_lang('CategoryDeleted'), 'success')
);
header("Location: $baseUrl");
@ -201,7 +201,7 @@ switch ($action) {
$em->flush();
Display::addFlash(
Display::return_message(get_lang('PortfolioItemDeleted'), 'success')
Display::return_message(get_lang('ItemDeleted'), 'success')
);
header("Location: $baseUrl");

@ -319,8 +319,8 @@ if ($_GET['action'] == 'add') {
$form->addRule('survey_code', '', 'maxlength', 20);
}
$form->addRule('survey_title', get_lang('ThisFieldIsRequired'), 'required');
$form->addRule('start_date', get_lang('InvalidDate'), $allowSurveyAvailabilityDatetime ? 'datetime': 'date');
$form->addRule('end_date', get_lang('InvalidDate'), $allowSurveyAvailabilityDatetime ? 'datetime': 'date');
$form->addRule('start_date', get_lang('InvalidDate'), $allowSurveyAvailabilityDatetime ? 'datetime' : 'date');
$form->addRule('end_date', get_lang('InvalidDate'), $allowSurveyAvailabilityDatetime ? 'datetime' : 'date');
$form->addRule(
['start_date', 'end_date'],
get_lang('StartDateShouldBeBeforeEndDate'),

@ -1883,7 +1883,8 @@ class SurveyManager
$invitation = Database::getManager()
->createQuery("
SELECT i FROM ChamiloCourseBundle:CSurveyInvitation i
INNER JOIN ChamiloCourseBundle:CSurvey s WITH s.code = i.surveyCode
INNER JOIN ChamiloCourseBundle:CSurvey s
WITH (s.code = i.surveyCode AND s.cId = i.cId AND s.sessionId = i.sessionId)
INNER JOIN ChamiloCoreBundle:ExtraFieldValues efv WITH efv.itemId = s.iid
INNER JOIN ChamiloCoreBundle:ExtraField ef WITH efv.field = ef.id
WHERE i.answered = 0

@ -41,9 +41,11 @@
<div class="block-title">
<h4 class="title" title="{{ item.title }}">
{% if item.visibility == constant('COURSE_VISIBILITY_CLOSED') and not item.current_user_is_teacher %}
{{ item.title_cut }} {{ item.code_course }}
{{ item.title_cut }}
<span class="code-title">{{ item.code_course }}</span>
{% else %}
<a title="{{ item.title }}" href="{{ item.link }}">{{ item.title_cut }} {{ item.code_course }}</a>
<a title="{{ item.title }}" href="{{ item.link }}">{{ item.title_cut }}</a>
<span class="code-title">{{ item.code_course }}</span>
{% endif %}
</h4>
</div>

@ -4,7 +4,9 @@
<div class="col-xs-12 col-sm-6 col-md-4">
<div class="items items-sessions">
<div class="image">
<img src="{{ course.image }}" class="img-responsive">
<a title="{{ course.name }}" href="{{ course.link }}">
<img src="{{ course.image }}" class="img-responsive">
</a>
{% if course.category != '' and show_category %}
<span class="category">{{ course.category }}</span>
<div class="cribbon"></div>
@ -31,7 +33,7 @@
<h4 class="title">
{% if course.visibility == constant('COURSE_VISIBILITY_CLOSED') %}
{{ course.title }}
<span class="code-title">{{ course.code }}</span>
<span class="code-title">{{ course.visual_code }}</span>
{% else %}
<a href="{{ course.link }}">{{ course.title }}</a>
{% endif %}

@ -137,3 +137,26 @@ $strings['PleaseSelectThePaymentMethodBeforeConfirmYourOrder'] = "Please select
$strings['NoPaymentOptionAvailable'] = 'No payment option available. Please report to the administrator.';
$strings['XIsOnlyPaymentMethodAvailable'] = '%s is the only payment method available for this purchase.';
$strings['hide_free_text'] = "Hide 'Free' text";
$strings['culqi_enable'] = "Enable culqi";
$strings['include_services'] = "Include services";
$strings['Services'] = "Services";
$strings['ServiceName'] = "Service name";
$strings['AppliesTo'] = "Applies to";
$strings['ListOfServicesOnSale'] = "List of services on sale";
$strings['GlobalConfig'] = "Global configuration";
$strings['WriteHereTheTermsAndConditionsOfYourECommerce'] = "Write here the terms and conditions of your e-commerce";
$strings['NewService'] = "New service";
$strings['Service'] = "Service";
$strings['ServiceInformation'] = "Service information";
$strings['EditService'] = "Edit service";
$strings['DeleteThisService'] = "Delete this service";
$strings['IConfirmIReadAndAcceptTermsAndCondition'] = "I confirm I read and accept the terms and conditions";
$strings['PleaseSelectTheCorrectInfoToApplyTheService'] = "Please select the correct info to apply the service";
$strings['SaleStatusCancelled'] = "Sale cancelled";
$strings['ServiceSaleInfo'] = "Service sale info";
$strings['ServiceId'] = "Service Id";
$strings['BoughtBy'] = "BoughtBy";
$strings['PurchaserUser'] = "Purchaser user";
$strings['Pending'] = "Pending";
$strings['Names'] = "Names";

@ -121,7 +121,7 @@ $strings['ApiPassword'] = "Mot de passe de l'API";
$strings['ApiSignature'] = "Signature de l'API";
$strings['InfoApiCredentials'] = "Pour générer vos données API pour intégrer votre compte PayPal à Chamilo, il vous faudra suivre les étapes suivantes";
$strings['InfoApiStepOne'] = "Aller dans l'option <strong>profil</strong> de PayPal, et ensuite dans <strong>Outils de vente</strong>";
$strings['InfoApiStepTwo'] = "Dans la section <strong>API d'accès</strong>, cloquer sur l'option <strong>Mettre à jour</strong>";
$strings['InfoApiStepTwo'] = "Dans la section <strong>API d'accès</strong>, cliquer sur l'option <strong>Mettre à jour</strong>";
$strings['InfoApiStepThree'] = "Dans l'option 2 de Configuration des données et permissions API, cliquer sur <strong>Voir signature API</strong>. Copier ces donées dans le formulaire de configuration de ce plugin";
$strings['ErrorOccurred'] = "<strong>Une erreur est survenue</strong>. Code: %s. Message: %s. Veuillez contacter l'administrateur de la plateforme";
$strings['VisibleInCatalog'] = "Visible dans le catalogue";
@ -136,3 +136,28 @@ $strings['SWIFT_help'] = "Format standard des codes d'identification de banque (
$strings['PleaseSelectThePaymentMethodBeforeConfirmYourOrder'] = 'Veuillez sélectionner votre méthode de paiement préférée avant de confirmer';
$strings['NoPaymentOptionAvailable'] = 'Aucune méthode de paiement disponible. Merci de bien vouloir rapporter ce problème à l\'administrateur.';
$strings['XIsOnlyPaymentMethodAvailable'] = '%s est la seule méthode de paiement disponible pour cet achat.';
$strings['public_main_menu_tab'] = "Montrer l'onglet dans le menu principal aux utilisateurs anonyme également";
$strings['culqi_enable'] = "Activé culqi";
$strings['include_services'] = "Inclure les services";
$strings['hide_free_text'] = "Cacher le texte 'Free' ou 'Gratuit'";
$strings['Services'] = "Services";
$strings['ServiceName'] = "Nom du service";
$strings['AppliesTo'] = "S'applique à";
$strings['ListOfServicesOnSale'] = "Liste de services en vente";
$strings['GlobalConfig'] = "Configuration globale";
$strings['WriteHereTheTermsAndConditionsOfYourECommerce'] = "Écrire les conditions de ventes de votre e-commerce";
$strings['NewService'] = "Nouveau service";
$strings['Service'] = "Service";
$strings['ServiceInformation'] = "Information sur le service";
$strings['EditService'] = "Edition du service";
$strings['DeleteThisService'] = "Supprimer ce service";
$strings['IConfirmIReadAndAcceptTermsAndCondition'] = "Je confirme que j'ai lu et que j'accepte les termes et conditions";
$strings['PleaseSelectTheCorrectInfoToApplyTheService'] = "Veuillez choisir l'information à appliquer au service";
$strings['SaleStatusCancelled'] = "Vente annulée";
$strings['ServiceSaleInfo'] = "Information de vente";
$strings['ServiceId'] = "Id du service";
$strings['BoughtBy'] = "Acheté par";
$strings['PurchaserUser'] = "Utilisateur acheteur";
$strings['Pending'] = "En attente";
$strings['Names'] = "Nom";

@ -140,8 +140,10 @@ $templateName = $plugin->get_lang('SalesReport');
$template = new Template($templateName);
$toolbar = "";
if ($paypalEnable == "true" && $commissionsEnable == "true") {
$toolbar = Display::toolbarButton(
$toolbar .= Display::toolbarButton(
$plugin->get_lang('PaypalPayoutCommissions'),
api_get_path(WEB_PLUGIN_PATH).'buycourses/src/paypal_payout.php',
'paypal',
@ -156,7 +158,7 @@ if ($paypalEnable == "true" && $commissionsEnable == "true") {
}
if ($commissionsEnable == "true") {
$toolbar = Display::toolbarButton(
$toolbar .= Display::toolbarButton(
$plugin->get_lang('PayoutReport'),
api_get_path(WEB_PLUGIN_PATH).'buycourses/src/payout_report.php',
'money',

@ -22,6 +22,7 @@ $strings['ContentsToShow'] = "Contents to show";
$strings['ContentsCourseDescription'] = 'Use section "Course description"> "Contents"';
$strings['ContentsIndexLearnpath'] = "Use learnpath index";
$strings['ContentsCustom'] = "Use custom content";
$strings['ContentsHide'] = "No show contents";
$strings['Dates'] = "Dates";
$strings['CourseDeliveryDates'] = "Course delivery dates";
$strings['Custom'] = "Custom";

@ -22,6 +22,7 @@ $strings['ContentsToShow'] = "Contenidos a mostrar";
$strings['ContentsCourseDescription'] = 'Usar apartado "Descripcion del curso" > "Contenidos"';
$strings['ContentsIndexLearnpath'] = "Usar indice de lecciones";
$strings['ContentsCustom'] = "Usar contenido personalizado";
$strings['ContentsHide'] = "No mostrar contenidos";
$strings['Dates'] = "Fechas";
$strings['CourseDeliveryDates'] = "Fechas de impartición del curso";
$strings['Custom'] = "Personalizado";

@ -321,6 +321,16 @@ $element = &$form->createElement(
);
$group[] = $element;
$element = &$form->createElement(
'radio',
'contents_type',
'',
get_lang('ContentsHide'),
3,
['id' => 'contents_type_3', 'onclick' => 'javascript: contentsTypeSwitchRadioButton();']
);
$group[] = $element;
$element = &$form->createElement(
'radio',
'contents_type',
@ -373,7 +383,7 @@ $option1 = &$form->createElement(
'',
get_lang('UseDateSessionAccess'),
0,
['id' => 'contents_type_0', 'onclick' => 'javascript: dateCertificateSwitchRadioButton0();']
['id' => 'date_change_0', 'onclick' => 'javascript: dateCertificateSwitchRadioButton0();']
);
$group[] = $option1;
@ -383,7 +393,7 @@ $option2 = &$form->createElement(
'',
get_lang('None'),
2,
['id' => 'contents_type_2', 'onclick' => 'javascript: dateCertificateSwitchRadioButton2();']
['id' => 'date_change_2', 'onclick' => 'javascript: dateCertificateSwitchRadioButton2();']
);
$group[] = $option2;
@ -393,7 +403,7 @@ $option3 = &$form->createElement(
'',
get_lang('Custom'),
1,
['id' => 'contents_type_1', 'onclick' => 'javascript: dateCertificateSwitchRadioButton1();']
['id' => 'date_change_1', 'onclick' => 'javascript: dateCertificateSwitchRadioButton1();']
);
$group[] = $option3;

@ -320,134 +320,136 @@ foreach ($userList as $userInfo) {
$htmlText .= '</div>';
// Rear certificate
$htmlText .= '<div class="caraB" style="page-break-before:always; margin:0px; padding:0px;">';
if ($infoCertificate['contents_type'] == 0) {
$courseDescription = new CourseDescription();
$contentDescription = $courseDescription->get_data_by_description_type(3, $courseId, 0);
$domd = new DOMDocument();
libxml_use_internal_errors(true);
if (isset($contentDescription['description_content'])) {
$domd->loadHTML($contentDescription['description_content']);
}
libxml_use_internal_errors(false);
$domx = new DOMXPath($domd);
$items = $domx->query("//li[@style]");
foreach ($items as $item) {
$item->removeAttribute("style");
}
$items = $domx->query("//span[@style]");
foreach ($items as $item) {
$item->removeAttribute("style");
}
$output = $domd->saveHTML();
$htmlText .= getIndexFiltered($output);
}
if ($infoCertificate['contents_type'] == 1) {
$items = [];
$categoriesTempList = learnpath::getCategories($courseId);
$categoryTest = new CLpCategory();
$categoryTest->setId(0);
$categoryTest->setName($plugin->get_lang('WithOutCategory'));
$categoryTest->setPosition(0);
$categories = [$categoryTest];
if (!empty($categoriesTempList)) {
$categories = array_merge($categories, $categoriesTempList);
}
foreach ($categories as $item) {
$categoryId = $item->getId();
if (!learnpath::categoryIsVisibleForStudent($item, api_get_user_entity($studentId))) {
continue;
if ($infoCertificate['contents_type'] != 3) {
$htmlText .= '<div class="caraB" style="page-break-before:always; margin:0px; padding:0px;">';
if ($infoCertificate['contents_type'] == 0) {
$courseDescription = new CourseDescription();
$contentDescription = $courseDescription->get_data_by_description_type(3, $courseId, 0);
$domd = new DOMDocument();
libxml_use_internal_errors(true);
if (isset($contentDescription['description_content'])) {
$domd->loadHTML($contentDescription['description_content']);
}
$sql = "SELECT 1
FROM $tblProperty
WHERE tool = 'learnpath_category'
AND ref = $categoryId
AND visibility = 0
AND (session_id = $sessionId OR session_id IS NULL)";
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
continue;
libxml_use_internal_errors(false);
$domx = new DOMXPath($domd);
$items = $domx->query("//li[@style]");
foreach ($items as $item) {
$item->removeAttribute("style");
}
$list = new LearnpathList(
$studentId,
$courseCode,
$sessionId,
null,
false,
$categoryId
);
$items = $domx->query("//span[@style]");
foreach ($items as $item) {
$item->removeAttribute("style");
}
$flat_list = $list->get_flat_list();
$output = $domd->saveHTML();
$htmlText .= getIndexFiltered($output);
}
if (empty($flat_list)) {
continue;
if ($infoCertificate['contents_type'] == 1) {
$items = [];
$categoriesTempList = learnpath::getCategories($courseId);
$categoryTest = new CLpCategory();
$categoryTest->setId(0);
$categoryTest->setName($plugin->get_lang('WithOutCategory'));
$categoryTest->setPosition(0);
$categories = [$categoryTest];
if (!empty($categoriesTempList)) {
$categories = array_merge($categories, $categoriesTempList);
}
if (count($categories) > 1 && count($flat_list) > 0) {
if ($item->getName() != $plugin->get_lang('WithOutCategory')) {
$items[] = '<h4 style="margin:0">'.$item->getName().'</h4>';
foreach ($categories as $item) {
$categoryId = $item->getId();
if (!learnpath::categoryIsVisibleForStudent($item, api_get_user_entity($studentId))) {
continue;
}
}
foreach ($flat_list as $learnpath) {
$lpId = $learnpath['lp_old_id'];
$sql = "SELECT 1
FROM $tblProperty
WHERE tool = 'learnpath'
AND ref = $lpId AND visibility = 0
WHERE tool = 'learnpath_category'
AND ref = $categoryId
AND visibility = 0
AND (session_id = $sessionId OR session_id IS NULL)";
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
continue;
}
$lpName = $learnpath['lp_name'];
$items[] = $lpName.'<br>';
$list = new LearnpathList(
$studentId,
$courseCode,
$sessionId,
null,
false,
$categoryId
);
$flat_list = $list->get_flat_list();
if (empty($flat_list)) {
continue;
}
if (count($categories) > 1 && count($flat_list) > 0) {
if ($item->getName() != $plugin->get_lang('WithOutCategory')) {
$items[] = '<h4 style="margin:0">'.$item->getName().'</h4>';
}
}
foreach ($flat_list as $learnpath) {
$lpId = $learnpath['lp_old_id'];
$sql = "SELECT 1
FROM $tblProperty
WHERE tool = 'learnpath'
AND ref = $lpId AND visibility = 0
AND (session_id = $sessionId OR session_id IS NULL)";
$res = Database::query($sql);
if (Database::num_rows($res) > 0) {
continue;
}
$lpName = $learnpath['lp_name'];
$items[] = $lpName.'<br>';
}
$items[] = '<br>';
}
$items[] = '<br>';
if (count($items) > 0) {
$htmlText .= '<table width="100%" class="contents-learnpath">';
$htmlText .= '<tr>';
$htmlText .= '<td>';
$i = 0;
foreach ($items as $value) {
if ($i == 50) {
$htmlText .= '</td><td>';
}
$htmlText .= $value;
$i++;
}
$htmlText .= '</td>';
$htmlText .= '</tr>';
$htmlText .= '</table>';
}
$htmlText .= '</td></table>';
}
if (count($items) > 0) {
if ($infoCertificate['contents_type'] == 2) {
$htmlText .= '<table width="100%" class="contents-learnpath">';
$htmlText .= '<tr>';
$htmlText .= '<td>';
$i = 0;
foreach ($items as $value) {
if ($i == 50) {
$htmlText .= '</td><td>';
}
$htmlText .= $value;
$i++;
}
$myContentHtml = strip_tags(
$infoCertificate['contents'],
'<p><b><strong><table><tr><td><th><span><i><li><ol><ul>'.
'<dd><dt><dl><br><hr><img><a><div><h1><h2><h3><h4><h5><h6>'
);
$htmlText .= $myContentHtml;
$htmlText .= '</td>';
$htmlText .= '</tr>';
$htmlText .= '</table>';
}
$htmlText .= '</td></table>';
}
if ($infoCertificate['contents_type'] == 2) {
$htmlText .= '<table width="100%" class="contents-learnpath">';
$htmlText .= '<tr>';
$htmlText .= '<td>';
$myContentHtml = strip_tags(
$infoCertificate['contents'],
'<p><b><strong><table><tr><td><th><span><i><li><ol><ul>'.
'<dd><dt><dl><br><hr><img><a><div><h1><h2><h3><h4><h5><h6>'
);
$htmlText .= $myContentHtml;
$htmlText .= '</td>';
$htmlText .= '</tr>';
$htmlText .= '</table>';
$htmlText .= '</div>';
}
$htmlText .= '</div>';
}
$htmlText .= '</body></html>';

@ -6,16 +6,17 @@
* main/img/icons/64/plugin_name.png
* main/img/icons/64/plugin_name_na.png
*/
/**
* Class OLPC_Peru_FilterPlugin
*/
class OLPC_Peru_FilterPlugin extends Plugin
{
public $blacklist_enabled_file = '/var/sqg/blacklists';
public $blacklists_dir = '/var/squidGuard/blacklists';
public $isCoursePlugin = true;
//When creating a new course, these settings are added to the course
public $course_settings = [
];
// When creating a new course, these settings are added to the course
public $course_settings = [];
public $course_settings_callback = true;
public $error = '';
@ -54,7 +55,7 @@ class OLPC_Peru_FilterPlugin extends Plugin
public function uninstall()
{
//Deleting course settings
$this->uninstall_course_fields_in_all_courses($this->course_settings);
$this->uninstall_course_fields_in_all_courses();
}
/**

@ -96,7 +96,7 @@ class Portfolio
* @var \Chamilo\CoreBundle\Entity\PortfolioCategory
*
* @ORM\ManyToOne(targetEntity="Chamilo\CoreBundle\Entity\PortfolioCategory", inversedBy="items")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id", onDelete="SET NULL")
*/
private $category;

@ -157,10 +157,10 @@ class CourseBuilder
*
* @param int $session_id
* @param string $courseCode
* @param bool $withBaseContent true if you want to get the elements that exists in the course and
* in the session, (session_id = 0 or session_id = X)
* @param array $parseOnlyToolList
* @param array $toolsFromPost
* @param bool $withBaseContent true if you want to get the elements that exists in the course and
* in the session, (session_id = 0 or session_id = X)
* @param array $parseOnlyToolList
* @param array $toolsFromPost
*
* @return Course The course object structure
*/
@ -665,10 +665,10 @@ class CourseBuilder
/**
* Build the Quizzes.
*
* @param int $session_id Internal session ID
* @param int $courseId Internal course ID
* @param bool $withBaseContent Whether to include content from the course without session or not
* @param array $idList If you want to restrict the structure to only the given IDs
* @param int $session_id Internal session ID
* @param int $courseId Internal course ID
* @param bool $withBaseContent Whether to include content from the course without session or not
* @param array $idList If you want to restrict the structure to only the given IDs
* @param bool $buildOrphanQuestions
*/
public function build_quizzes(
@ -754,10 +754,9 @@ class CourseBuilder
/**
* Build the Quiz-Questions.
*
* @param int $courseId Internal course ID
* @param int $courseId Internal course ID
* @param array $questionList
* @param bool $buildOrphanQuestions
*
*/
public function build_quiz_questions($courseId = 0, $questionList = [], $buildOrphanQuestions = true)
{
@ -923,7 +922,7 @@ class CourseBuilder
/**
* @deprecated
* Build the orphan questions.
* Build the orphan questions
*/
public function build_quiz_orphan_questions()
{

@ -1909,7 +1909,6 @@ class CourseRestorer
Database::query($sql);
}
}
}
}
}

@ -48,13 +48,14 @@ class CourseSelectForm
return $list;
}
/**
* Display the form.
*
* @param array $course
* @param array $hidden_fields hidden fields to add to the form
* @param bool $avoidSerialize the document array will be serialize.
* This is used in the course_copy.php file
* @param array $hidden_fields hidden fields to add to the form
* @param bool $avoidSerialize the document array will be serialize.
* This is used in the course_copy.php file
* @param bool $avoidCourseInForm
*/
public static function display_form(
@ -63,8 +64,7 @@ class CourseSelectForm
$avoidSerialize = false,
$avoidCourseInForm = false
) {
global $charset;
?>
global $charset; ?>
<script>
function exp(item) {
el = document.getElementById('div_'+item);
@ -486,8 +486,8 @@ class CourseSelectForm
/**
* Get the posted course.
*
* @param string $from who calls the function?
* It can be copy_course, create_backup, import_backup or recycle_course
* @param string $from who calls the function?
* It can be copy_course, create_backup, import_backup or recycle_course
* @param int $session_id
* @param string $course_code
* @param Course $postedCourse

@ -466,11 +466,9 @@ class FeatureContext extends MinkContext
public function iShouldNotSeeAnIconWithTitle($value)
{
$el = $this->getSession()->getPage()->find('xpath', "//img[@title='$value']");
if (null !== $el) {
throw new Exception(
'Found an icon with title: '.$value
);
if (null === $el) {
return true;
}
return true;
return false;
}
}

@ -54,14 +54,14 @@ Feature: LP tool
And I follow "Delete"
Then I should not see "LP category 1"
Scenario: Check the PDF export in LP list
Scenario: Check the PDF export in LP list if hide SCORM PDF link is false
Given I am on "/main/admin/settings.php?category=Course"
And I check the "hide_scorm_pdf_link" radio button with "false" value
And I press "Save settings"
And I am on "/main/lp/lp_controller.php?cidReq=TEMP&action=list&isStudentView=true"
Then I should see an icon with title "Export to PDF"
Scenario: Check the PDF export in LP list
Scenario: Check the PDF export in LP list if hide SCORM PDF link is true
Given I am on "/main/admin/settings.php?category=Course"
And I check the "hide_scorm_pdf_link" radio button with "true" value
And I press "Save settings"

Loading…
Cancel
Save