Permalink
Browse files

Merge branch 'wip-MDL-38708-master' of git://github.com/marinaglancy/…

…moodle

Conflicts:
	version.php
  • Loading branch information...
2 parents 6ed18a6 + d1f8c1b commit 37240ce5c6f4e1dc23708a6f6e7752a78f961cef @nebgor nebgor committed Apr 4, 2013
View
4 admin/settings/appearance.php
@@ -200,6 +200,10 @@
new lang_string('courselistshortnames_desc', 'admin'), 0));
$temp->add(new admin_setting_configtext('coursesperpage', new lang_string('coursesperpage', 'admin'), new lang_string('configcoursesperpage', 'admin'), 20, PARAM_INT));
$temp->add(new admin_setting_configtext('courseswithsummarieslimit', new lang_string('courseswithsummarieslimit', 'admin'), new lang_string('configcourseswithsummarieslimit', 'admin'), 10, PARAM_INT));
+ $temp->add(new admin_setting_configtext('courseoverviewfileslimit', new lang_string('courseoverviewfileslimit'),
+ new lang_string('configcourseoverviewfileslimit', 'admin'), 1, PARAM_INT));
+ $temp->add(new admin_setting_configtext('courseoverviewfilesext', new lang_string('courseoverviewfilesext'),
+ new lang_string('configcourseoverviewfilesext', 'admin'), '.jpg,.gif,.png'));
$ADMIN->add('appearance', $temp);
$temp = new admin_settingpage('ajax', new lang_string('ajaxuse'));
View
1 backup/moodle2/backup_stepslib.php
@@ -511,6 +511,7 @@ protected function define_structure() {
$course->annotate_ids('grouping', 'defaultgroupingid');
$course->annotate_files('course', 'summary', null);
+ $course->annotate_files('course', 'overviewfiles', null);
$course->annotate_files('course', 'legacy', null);
// Return root element ($course)
View
1 backup/moodle2/restore_stepslib.php
@@ -1459,6 +1459,7 @@ protected function after_execute() {
// Add course related files, without itemid to match
$this->add_related_files('course', 'summary', null);
+ $this->add_related_files('course', 'overviewfiles', null);
// Deal with legacy allowed modules.
if ($this->legacyrestrictmodules) {
View
7 course/edit.php
@@ -66,10 +66,14 @@
// Prepare course and the editor
$editoroptions = array('maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true);
+$overviewfilesoptions = course_overviewfiles_options($course);
if (!empty($course)) {
//add context for editor
$editoroptions['context'] = $coursecontext;
$course = file_prepare_standard_editor($course, 'summary', $editoroptions, $coursecontext, 'course', 'summary', 0);
+ if ($overviewfilesoptions) {
+ file_prepare_standard_filemanager($course, 'overviewfiles', $overviewfilesoptions, $coursecontext, 'course', 'overviewfiles', 0);
+ }
// Inject current aliases
$aliases = $DB->get_records('role_names', array('contextid'=>$coursecontext->id));
@@ -81,6 +85,9 @@
//editor should respect category context if course context is not set.
$editoroptions['context'] = $catcontext;
$course = file_prepare_standard_editor($course, 'summary', $editoroptions, null, 'course', 'summary', null);
+ if ($overviewfilesoptions) {
+ file_prepare_standard_filemanager($course, 'overviewfiles', $overviewfilesoptions, null, 'course', 'overviewfiles', 0);
+ }
}
// first create the form
View
9 course/edit_form.php
@@ -105,9 +105,16 @@ function definition() {
$mform->addElement('editor','summary_editor', get_string('coursesummary'), null, $editoroptions);
$mform->addHelpButton('summary_editor', 'coursesummary');
$mform->setType('summary_editor', PARAM_RAW);
+ $summaryfields = 'summary_editor';
+
+ if ($overviewfilesoptions = course_overviewfiles_options($course)) {
+ $mform->addElement('filemanager', 'overviewfiles_filemanager', get_string('courseoverviewfiles'), null, $overviewfilesoptions);
+ $mform->addHelpButton('overviewfiles_filemanager', 'courseoverviewfiles');
+ $summaryfields .= ',overviewfiles_filemanager';
+ }
if (!empty($course->id) and !has_capability('moodle/course:changesummary', $coursecontext)) {
- $mform->hardFreeze('summary_editor');
+ $mform->hardFreeze($summaryfields);
}
$courseformats = get_sorted_course_formats(true);
View
54 course/lib.php
@@ -2177,6 +2177,53 @@ function save_local_role_names($courseid, $data) {
}
/**
+ * Returns options to use in course overviewfiles filemanager
+ *
+ * @param null|stdClass|course_in_list|int $course either object that has 'id' property or just the course id;
+ * may be empty if course does not exist yet (course create form)
+ * @return array|null array of options such as maxfiles, maxbytes, accepted_types, etc.
+ * or null if overviewfiles are disabled
+ */
+function course_overviewfiles_options($course) {
+ global $CFG;
+ if (empty($CFG->courseoverviewfileslimit)) {
+ return null;
+ }
+ $accepted_types = preg_split('/\s*,\s*/', trim($CFG->courseoverviewfilesext), -1, PREG_SPLIT_NO_EMPTY);
+ if (in_array('*', $accepted_types) || empty($accepted_types)) {
+ $accepted_types = '*';
+ } else {
+ // Since config for $CFG->courseoverviewfilesext is a text box, human factor must be considered.
+ // Make sure extensions are prefixed with dot unless they are valid typegroups
+ foreach ($accepted_types as $i => $type) {
+ if (substr($type, 0, 1) !== '.') {
+ require_once($CFG->libdir. '/filelib.php');
+ if (!count(file_get_typegroup('extension', $type))) {
+ // It does not start with dot and is not a valid typegroup, this is most likely extension.
+ $accepted_types[$i] = '.'. $type;
+ $corrected = true;
+ }
+ }
+ }
+ if (!empty($corrected)) {
+ set_config('courseoverviewfilesext', join(',', $accepted_types));
+ }
+ }
+ $options = array(
+ 'maxfiles' => $CFG->courseoverviewfileslimit,
+ 'maxbytes' => $CFG->maxbytes,
+ 'subdirs' => 0,
+ 'accepted_types' => $accepted_types
+ );
+ if (!empty($course->id)) {
+ $options['context'] = context_course::instance($course->id);
+ } else if (is_int($course) && $course > 0) {
+ $options['context'] = context_course::instance($course);
+ }
+ return $options;
+}
+
+/**
* Create a course and either return a $course object
*
* Please note this functions does not verify any access control,
@@ -2233,6 +2280,10 @@ function create_course($data, $editoroptions = NULL) {
$DB->set_field('course', 'summary', $data->summary, array('id'=>$newcourseid));
$DB->set_field('course', 'summaryformat', $data->summary_format, array('id'=>$newcourseid));
}
+ if ($overviewfilesoptions = course_overviewfiles_options($newcourseid)) {
+ // Save the course overviewfiles
+ $data = file_postupdate_standard_filemanager($data, 'overviewfiles', $overviewfilesoptions, $context, 'course', 'overviewfiles', 0);
+ }
// update course format options
course_get_format($newcourseid)->update_course_format_options($data);
@@ -2287,6 +2338,9 @@ function update_course($data, $editoroptions = NULL) {
if ($editoroptions) {
$data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'summary', 0);
}
+ if ($overviewfilesoptions = course_overviewfiles_options($data->id)) {
+ $data = file_postupdate_standard_filemanager($data, 'overviewfiles', $overviewfilesoptions, $context, 'course', 'overviewfiles', 0);
+ }
if (!isset($data->category) or empty($data->category)) {
// prevent nulls and 0 in category field
View
19 course/renderer.php
@@ -1070,7 +1070,7 @@ protected function coursecat_coursebox(coursecat_helper $chelper, $course, $addi
// If we display course in collapsed form but the course has summary or course contacts, display the link to the info page.
$content .= html_writer::start_tag('div', array('class' => 'moreinfo'));
if ($chelper->get_show_courses() < self::COURSECAT_SHOW_COURSES_EXPANDED) {
- if ($course->has_summary() || $course->has_course_contacts()) {
+ if ($course->has_summary() || $course->has_course_contacts() || $course->has_course_overviewfiles()) {
$url = new moodle_url('/course/info.php', array('id' => $course->id));
$image = html_writer::empty_tag('img', array('src' => $this->output->pix_url('i/info'),
'alt' => $this->strings->summary));
@@ -1126,6 +1126,23 @@ protected function coursecat_coursebox_content(coursecat_helper $chelper, $cours
$content .= html_writer::end_tag('div'); // .summary
}
+ // display course overview files
+ foreach ($course->get_course_overviewfiles() as $file) {
+ $isimage = $file->is_valid_image();
+ $url = file_encode_url("$CFG->wwwroot/pluginfile.php",
+ '/'. $file->get_contextid(). '/'. $file->get_component(). '/'.
+ $file->get_filearea(). $file->get_filepath(). $file->get_filename(), !$isimage);
+ if ($isimage) {
+ $content .= html_writer::tag('div',
+ html_writer::empty_tag('img', array('src' => $url)),
+ array('class' => 'courseimage'));
+ } else {
+ $content .= html_writer::tag('div',
+ html_writer::link($url, $file->get_filename()),
+ array('class' => 'coursefile'));
+ }
+ }
+
// display course contacts. See course_in_list::get_course_contacts()
if ($course->has_course_contacts()) {
$content .= html_writer::start_tag('ul', array('class' => 'teachers'));
View
2 lang/en/admin.php
@@ -152,6 +152,8 @@
$string['configcookiehttponly'] = 'Enables new PHP 5.2.0 feature - browsers are instructed to send cookie with real http requests only, cookies should not be accessible by scripting languages. This is not supported in all browsers and it may not be fully compatible with current code. It helps to prevent some types of XSS attacks.';
$string['configcookiesecure'] = 'If server is accepting only https connections it is recommended to enable sending of secure cookies. If enabled please make sure that web server is not accepting http:// or set up permanent redirection to https:// address. When <em>wwwroot</em> address does not start with https:// this setting is turned off automatically.';
$string['configcountry'] = 'If you set a country here, then this country will be selected by default on new user accounts. To force users to choose a country, just leave this unset.';
+$string['configcourseoverviewfilesext'] = 'Comma-separated list of allowed course overview files extensions';
+$string['configcourseoverviewfileslimit'] = 'Limit the number of files course managers are allowed to add to the course. They will be accessible by anyone from outside of the course just like course name and/or summary';
$string['configcourserequestnotify'] = 'Type username of user to be notified when new course requested.';
$string['configcourserequestnotify2'] = 'Users who will be notified when a course is requested. Only users who can approve course requests are listed here.';
$string['configcoursesperpage'] = 'Enter the number of courses to be displayed per page in a course listing.';
View
4 lang/en/moodle.php
@@ -322,6 +322,10 @@
$string['coursehelpnumberweeks'] = 'Number of sections in the course (applies to certain course formats only).';
$string['coursehelpshowgrades'] = 'Enable the display of the gradebook. It does not prevent grades from being displayed within the individual activities.';
$string['coursehidden'] = 'This course is currently unavailable to students';
+$string['courseoverviewfiles'] = 'Course overview files';
+$string['courseoverviewfilesext'] = 'Course overview files extensions';
+$string['courseoverviewfileslimit'] = 'Course overview files limit';
+$string['courseoverviewfiles_help'] = 'Course overview files (usually images) are displayed in the list of courses together with summary';
$string['courseinfo'] = 'Course info';
$string['coursemessage'] = 'Message course users';
$string['coursenotaccessible'] = 'This course does not allow public access';
View
1 lang/en/repository.php
@@ -38,6 +38,7 @@
$string['activitybackup'] = 'Activity backup';
$string['areacategoryintro'] = 'Category introduction';
$string['areacourseintro'] = 'Course introduction';
+$string['areacourseoverviewfiles'] = 'Course overview files';
$string['arearoot'] = 'System';
$string['areauserdraft'] = 'Drafts';
$string['areauserbackup'] = 'User backup';
View
47 lib/coursecatlib.php
@@ -2058,6 +2058,53 @@ public function get_course_contacts() {
return $this->coursecontacts;
}
+ /**
+ * Checks if course has any associated overview files
+ *
+ * @return bool
+ */
+ public function has_course_overviewfiles() {
+ global $CFG;
+ if (empty($CFG->courseoverviewfileslimit)) {
+ return 0;
+ }
+ require_once($CFG->libdir. '/filestorage/file_storage.php');
+ $fs = get_file_storage();
+ $context = context_course::instance($this->id);
+ return $fs->is_area_empty($context->id, 'course', 'overviewfiles');
+ }
+
+ /**
+ * Returns all course overview files
+ *
+ * @return array array of stored_file objects
+ */
+ public function get_course_overviewfiles() {
+ global $CFG;
+ if (empty($CFG->courseoverviewfileslimit)) {
+ return array();
+ }
+ require_once($CFG->libdir. '/filestorage/file_storage.php');
+ $fs = get_file_storage();
+ $context = context_course::instance($this->id);
+ $files = $fs->get_area_files($context->id, 'course', 'overviewfiles', false, 'filename', false);
+ if (count($files)) {
+ $overviewfilesoptions = course_overviewfiles_options($this->id);
+ $acceptedtypes = $overviewfilesoptions['accepted_types'];
+ if ($acceptedtypes !== '*') {
+ // filter only files with allowed extensions
+ require_once($CFG->libdir. '/filelib.php');
+ $files = array_filter($files, function ($file) use ($acceptedtypes) {
+ return file_extension_in_typegroup($file->get_filename(), $acceptedtypes);} );
+ }
+ if (count($files) > $CFG->courseoverviewfileslimit) {
+ // return no more than $CFG->courseoverviewfileslimit files
+ $files = array_slice($files, 0, $CFG->courseoverviewfileslimit, true);
+ }
+ }
+ return $files;
+ }
+
// ====== magic methods =======
public function __isset($name) {
View
35 lib/filebrowser/file_info_context_course.php
@@ -121,6 +121,40 @@ protected function get_area_course_summary($itemid, $filepath, $filename) {
}
/**
+ * Gets a stored file for the course images filearea directory
+ *
+ * @param int $itemid item ID
+ * @param string $filepath file path
+ * @param string $filename file name
+ * @return file_info|null file_info instance or null if not found or access not allowed
+ */
+ protected function get_area_course_overviewfiles($itemid, $filepath, $filename) {
+ global $CFG;
+
+ if (!has_capability('moodle/course:update', $this->context)) {
+ return null;
+ }
+ if (is_null($itemid)) {
+ return $this;
+ }
+
+ $fs = get_file_storage();
+
+ $filepath = is_null($filepath) ? '/' : $filepath;
+ $filename = is_null($filename) ? '.' : $filename;
+ if (!$storedfile = $fs->get_file($this->context->id, 'course', 'overviewfiles', 0, $filepath, $filename)) {
+ if ($filepath === '/' and $filename === '.') {
+ $storedfile = new virtual_root_file($this->context->id, 'course', 'overviewfiles', 0);
+ } else {
+ // not found
+ return null;
+ }
+ }
+ $urlbase = $CFG->wwwroot.'/pluginfile.php';
+ return new file_info_stored($this->browser, $this->context, $storedfile, $urlbase, get_string('areacourseoverviewfiles', 'repository'), false, true, true, false);
+ }
+
+ /**
* Gets a stored file for the course section filearea directory
*
* @param int $itemid item ID
@@ -365,6 +399,7 @@ public function get_children() {
private function get_filtered_children($extensions = '*', $countonly = false, $returnemptyfolders = false) {
$areas = array(
array('course', 'summary'),
+ array('course', 'overviewfiles'),
array('course', 'section'),
array('backup', 'section'),
array('backup', 'course'),
View
4 lib/filelib.php
@@ -4100,14 +4100,14 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
send_file_not_found();
}
- if ($filearea === 'summary') {
+ if ($filearea === 'summary' || $filearea === 'overviewfiles') {
if ($CFG->forcelogin) {
require_login();
}
$filename = array_pop($args);
$filepath = $args ? '/'.implode('/', $args).'/' : '/';
- if (!$file = $fs->get_file($context->id, 'course', 'summary', 0, $filepath, $filename) or $file->is_directory()) {
+ if (!$file = $fs->get_file($context->id, 'course', $filearea, 0, $filepath, $filename) or $file->is_directory()) {
send_file_not_found();
}
View
9 theme/base/style/course.css
@@ -116,7 +116,9 @@ li.section.hidden span.commands a.editing_show {cursor:default;}
.coursebox .name a {display:block;background-image:url([[pix:moodle|i/course]]);background-repeat: no-repeat;padding-left:21px;background-position: center left;}
.coursebox.remotehost .name a {background-image:url([[pix:moodle|i/mnethost]]);}
.coursebox .name,
-.coursebox .teachers {float:left;width: 40%;}
+.coursebox .teachers,
+.coursebox .content .courseimage,
+.coursebox .content .coursefile {float:left;width:40%;clear:left;}
.coursebox .teachers li {list-style-type:none;padding:0;margin:0;}
.coursebox .enrolmenticons {padding:3px 0;float:right;}
.coursebox .moreinfo {padding:3px 0;float:right;}
@@ -127,10 +129,13 @@ li.section.hidden span.commands a.editing_show {cursor:default;}
.coursebox .coursecat {float:right;width: 55%;}
.coursebox .coursecat {text-align:right;clear:right;}
.coursebox.remotecoursebox .remotecourseinfo {float:left;width: 40%;}
+.coursebox .content .courseimage img {max-width:100px;max-height:100px;}
.dir-rtl .coursebox .name a {padding-left:0;padding-right:21px;background-position: center right;}
.dir-rtl .coursebox .name,
-.dir-rtl .coursebox .teachers {float:right;}
+.dir-rtl .coursebox .teachers,
+.dir-rtl .coursebox .content .courseimage,
+.dir-rtl .coursebox .content .coursefile {float:right;clear:right;}
.dir-rtl .coursebox .enrolmenticons,
.dir-rtl .coursebox .moreinfo {float:left;}
.dir-rtl .coursebox .summary,
View
4 theme/formal_white/style/course.css
@@ -17,7 +17,9 @@
.coursebox .content {font-size:90%;}
.coursebox .teachers {margin:5px 1em;}
.coursebox .summary,
-.coursebox .coursecat {margin:5px;}
+.coursebox .coursecat,
+.coursebox .content .courseimage,
+.coursebox .content .coursefile {margin:5px;}
.coursebox > .content:after,
.coursebox > .info:after {clear:both;content:".";display:block;height:0;min-width:0;visibility:hidden;}
View
16 theme/magazine/style/core.css
@@ -924,15 +924,25 @@ div.coursebox h3.name a {
padding-left: 5px;
}
-.dir-rtl .coursebox ul.teachers {
+.coursebox .content .courseimage,
+.coursebox .content .coursefile {
+ padding-left: 5px;
+}
+
+.dir-rtl .coursebox ul.teachers,
+.dir-rtl .coursebox .content .courseimage,
+.dir-rtl .coursebox .content .coursefile {
padding-right: 5px;
}
-.coursebox ul.teachers li {
+.coursebox ul.teachers li,
+.coursebox .coursecat {
font-size: 10px;
}
-.coursebox ul.teachers li a {
+.coursebox ul.teachers li a,
+.coursebox .coursecat a,
+.coursebox .content .coursefile a {
font-size: 11px;
}
View
2 theme/splash/style/core.css
@@ -358,7 +358,7 @@ li.activity {
padding-bottom: 5px;
}
.coursebox .summary{
- padding: 10px 0;
+ padding: 0 0 10px 0;
}
.que .info{
width: 10em;
View
2 theme/standard/style/course.css
@@ -82,6 +82,8 @@
.coursebox .teachers {padding:3px 0 3px 21px;margin:0;font-size:0.9em;}
.coursebox .coursecat,
.coursebox .summary,
+.coursebox .courseimage,
+.coursebox .coursefile,
.coursebox.remotecoursebox .remotecourseinfo {padding:3px 5px;font-size:0.9em;}
.dir-rtl .coursebox .teachers {padding:3px 21px 3px 0;}
View
2 version.php
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
-$version = 2013040300.01; // YYYYMMDD = weekly release date of this DEV branch
+$version = 2013040300.02; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches
// .XX = incremental changes

0 comments on commit 37240ce

Please sign in to comment.