Merge branch 'wip-MDL-51132-master' of https://github.com/marinaglancy/moodle

This commit is contained in:
Dan Poltawski
2015-09-08 10:46:38 +01:00
34 changed files with 741 additions and 1133 deletions
+1 -100
View File
@@ -95,106 +95,7 @@ class block_tags extends block_base {
require_once($CFG->dirroot.'/tag/locallib.php');
if (empty($CFG->block_tags_showcoursetags) or !$CFG->block_tags_showcoursetags) {
$this->content->text = tag_print_cloud(null, $this->config->numberoftags, true);
} else {
// Start of show course tags section.
require_once($CFG->dirroot.'/tag/coursetagslib.php');
// Page awareness.
$tagtype = 'all';
if ($SCRIPT == '/my/index.php') {
$tagtype = 'my';
} else if (isset($this->page->course->id)) {
if ($this->page->course->id != SITEID) {
$tagtype = 'course';
}
}
// DB hits to get groups of marked up tags (if available).
// TODO check whether time limited personal tags are required.
$content = '';
$moretags = new moodle_url('/tag/coursetags_more.php', array('show'=>$tagtype));
if ($tagtype == 'all') {
$tags = coursetag_get_tags(0, 0, $this->config->tagtype, $this->config->numberoftags);
} else if ($tagtype == 'course') {
$tags = coursetag_get_tags($this->page->course->id, 0, $this->config->tagtype, $this->config->numberoftags);
$moretags->param('courseid', $this->page->course->id);
} else if ($tagtype == 'my') {
$tags = coursetag_get_tags(0, $USER->id, $this->config->tagtype, $this->config->numberoftags);
}
$tagcloud = tag_print_cloud($tags, 150, true);
if (!$tagcloud) {
$tagcloud = get_string('notagsyet', 'block_tags');
}
// Prepare the divs that display the groups of tags.
$content = get_string($tagtype."tags", 'block_tags').
'<div class="coursetag_list">'.$tagcloud.'</div>
<div class="coursetag_morelink">
<a href="'.$moretags->out().'" title="'.get_string('moretags', 'block_tags').'">'
.get_string('more', 'block_tags').'</a>
</div>';
// Add javascript.
coursetag_get_jscript();
// Add the divs (containing the tags) to the block's content.
$this->content->text .= $content;
// Add the input form section (allowing a user to tag the current course) and navigation, or login message.
if (isloggedin() && !isguestuser()) {
// Only show the input form on course pages for those allowed (or not barred).
if ($tagtype == 'course' &&
has_capability('moodle/tag:create', context_course::instance($this->page->course->id))) {
$buttonadd = get_string('add', 'block_tags');
$arrowtitle = get_string('arrowtitle', 'block_tags');
$edittags = get_string('edittags', 'block_tags');
$sesskey = sesskey();
$arrowright = $OUTPUT->pix_url('t/arrow_left');
$redirect = $this->page->url->out();
$this->content->footer .= <<<EOT
<hr />
<form action="{$CFG->wwwroot}/tag/coursetags_add.php" method="post" id="coursetag"
onsubmit="return ctags_checkinput(this.coursetag_new_tag.value)">
<div style="display: none;">
<input type="hidden" name="entryid" value="$COURSE->id" />
<input type="hidden" name="userid" value="$USER->id" />
<input type="hidden" name="sesskey" value="$sesskey" />
<input type="hidden" name="returnurl" value="$redirect" />
</div>
<div class="coursetag_form_wrapper">
<div class="coursetag_form_positioner">
<div class="coursetag_form_input1">
<input type="text" name="coursetag_sug_keyword" class="coursetag_form_input1a" disabled="disabled" />
</div>
<div class="coursetag_form_input2">
<input type="text" name="coursetag_new_tag" id="coursetag_new_tag"
class="coursetag_form_input2a" onfocus="ctags_getKeywords()" onkeyup="ctags_getKeywords()" maxlength="50" />
</div>
<div class="coursetag_form_input3" id="coursetag_sug_btn">
<a title="$arrowtitle">
<img src="$arrowright" width="10" height="10" alt="enter" onclick="ctags_setKeywords()" />
</a>
</div>
</div>
<div style="display: inline;">
<button type="submit">$buttonadd</button>
<a href="$CFG->wwwroot/tag/coursetags_edit.php?courseid=$COURSE->id" title="$edittags">$edittags</a>
</div>
</div>
</form>
EOT;
}
} else {
// If not logged in.
$this->content->footer = '<hr />'.get_string('please', 'block_tags').'
<a href="'.get_login_url().'">'.get_string('login', 'block_tags').'
</a> '.get_string('tagunits', 'block_tags');
}
}
// End of show course tags section.
$this->content->text = tag_print_cloud(null, $this->config->numberoftags, true);
return $this->content;
}
-63
View File
@@ -1,63 +0,0 @@
/**
* coursetags.js
* @author [email protected] July07
*
* getKeywords modified from an original script (Auto Complete Textfield)
* from The JavaScript Source http://javascript.internet.com
* originally created by: Timothy Groves http://www.brandspankingnew.net/
*/
function ctags_show_div(mydiv) {
for(x in coursetagdivs) {
if(mydiv == coursetagdivs[x]) {
document.getElementById(coursetagdivs[x]).style.display="block";
} else {
document.getElementById(coursetagdivs[x]).style.display="none";
}
}
return false;
}
var sug = "";
var sug_disp = "";
function ctags_getKeywords() {
/*
// This 'workaround' removing the xhtml strict form autocomplete="off" needs to
// be added to the body onload() script to work - but decided not to include
// (having the browser list might help with screen readers more than this script)
// document.forms['coursetag'].setAttribute("autocomplete", "off");
*/
var input = document.forms['coursetag'].coursetag_new_tag.value;
var len = input.length;
sug_disp = ""; sug = "";
if (input.length) {
for (ele in coursetag_tags)
{
if (coursetag_tags[ele].substr(0,len).toLowerCase() == input.toLowerCase())
{
sug_disp = input + coursetag_tags[ele].substr(len);
sug = coursetag_tags[ele];
break;
}
}
}
document.forms['coursetag'].coursetag_sug_keyword.value = sug_disp;
if (!sug.length || input == sug_disp) {
document.getElementById('coursetag_sug_btn').style.display = "none";
} else {
document.getElementById('coursetag_sug_btn').style.display = "block";
}
}
function ctags_setKeywords() {
document.forms['coursetag'].coursetag_new_tag.value = sug;
ctags_hideSug();
}
function ctags_hideSug() {
document.forms['coursetag'].coursetag_sug_keyword.value = "";
document.getElementById('coursetag_sug_btn').style.display = "none";
}
+9 -6
View File
@@ -22,13 +22,19 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['configtitle'] = 'Block title';
$string['disabledtags'] = 'Tags are disabled';
$string['defaultdisplay'] = 'Tag type to display';
$string['pluginname'] = 'Tags';
$string['tags:addinstance'] = 'Add a new tags block';
$string['tags:myaddinstance'] = 'Add a new tags block to Dashboard';
// Deprecated since 3.0
$string['add'] = 'Add';
$string['alltags'] = 'All tags:';
$string['arrowtitle'] = 'Click here to enter the suggested text (grey letters).';
$string['configtitle'] = 'Block title';
$string['coursetags'] = 'Course tags:';
$string['disabledtags'] = 'Tags are disabled';
$string['defaultdisplay'] = 'Tag type to display';
$string['edit'] = 'edit...';
$string['editdeletemytag'] = 'Delete tag from this course:';
$string['editmytags'] = 'My tags - shortcuts to all your tagged courses.';
@@ -65,13 +71,10 @@ $string['mycoursetags'] = 'My course tags:';
$string['mytags'] = 'My tags:';
$string['notagsyet'] = 'No tags yet';
$string['please'] = 'Please';
$string['pluginname'] = 'Tags';
$string['select'] = 'Select...';
$string['showcoursetags'] = 'Show course tags';
$string['showcoursetagsdef'] = 'Display the course tagging features in the tags block, allowing students to tag courses.';
$string['suggestedtagthisunit'] = 'Suggested tag to this course:';
$string['tags'] = 'tags';
$string['tags:addinstance'] = 'Add a new tags block';
$string['tags:myaddinstance'] = 'Add a new tags block to Dashboard';
$string['tagthisunit'] = 'Tag this course:';
$string['tagunits'] = 'to tag your favourite courses';
+42
View File
@@ -0,0 +1,42 @@
add,block_tags
alltags,block_tags
arrowtitle,block_tags
coursetags,block_tags
edit,block_tags
editdeletemytag,block_tags
editmytags,block_tags
editmytagsfor,block_tags
editnopersonaltags,block_tags
edittags,block_tags
edittagthisunit,block_tags
editthiscoursetags,block_tags
edittitle,block_tags
entries,block_tags
entry,block_tags
jserror1,block_tags
jserror2,block_tags
login,block_tags
more,block_tags
moreorder,block_tags
moreorderalpha,block_tags
moreorderdate,block_tags
moreorderpop,block_tags
moreshow,block_tags
moreshowalltags,block_tags
moreshowcommtags,block_tags
moreshowcoursetags,block_tags
moreshowmytags,block_tags
moreshowofficialtags,block_tags
moretags,block_tags
moretitle,block_tags
morewelcome,block_tags
mytags,block_tags
notagsyet,block_tags
please,block_tags
select,block_tags
showcoursetags,block_tags
showcoursetagsdef,block_tags
suggestedtagthisunit,block_tags
tags,block_tags
tagthisunit,block_tags
tagunits,block_tags
-30
View File
@@ -1,30 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Settings for the tags block.
*
* @package block_tags
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
$settings->add(new admin_setting_configcheckbox('block_tags_showcoursetags', get_string('showcoursetags', 'block_tags'),
get_string('showcoursetagsdef', 'block_tags'), 0));
}
-11
View File
@@ -1,11 +0,0 @@
.block_tags {}
.block_tags #coursetag {}
.block_tags #coursetag .coursetag_form_wrapper {}
.block_tags #coursetag .coursetag_form_wrapper .coursetag_form_positioner {position: relative;}
.block_tags #coursetag .coursetag_form_wrapper .coursetag_form_positioner .coursetag_form_input1 {position: relative;top: 0;left: 0;z-index: 1;width:100%;}
.block_tags #coursetag .coursetag_form_wrapper .coursetag_form_positioner .coursetag_form_input2 {position: absolute;top: 0;left: 0;z-index: 2;width:100%;}
.block_tags #coursetag .coursetag_form_wrapper .coursetag_form_positioner .coursetag_form_input3 {position: absolute;top: 3px;left: 12.8em;display: none;}
.block_tags #coursetag .coursetag_form_wrapper .coursetag_form_positioner .coursetag_form_input1a {background-color: white; border: 1px solid #999;width: 12em;padding: 2px;}
.block_tags #coursetag .coursetag_form_wrapper .coursetag_form_positioner .coursetag_form_input2a {background-color: transparent; border: 1px solid #999;width: 12em;color: #669954;padding: 2px;}
.block_tags .coursetag_morelink {}
.block_tags .coursetag_list {}
@@ -1,64 +0,0 @@
@block @block_tags @core_tag
Feature: Block tags displaying course tags
In order to tag courses
As a user
I need to be able to use the block tags
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | c1 |
And the following "tags" exist:
| name | tagtype |
| Neverusedtag | official |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | c1 | editingteacher |
| student1 | c1 | student |
| student2 | c1 | student |
And I log in as "admin"
And I set the following administration settings values:
| Show course tags | 1 |
And I log out
Scenario: Add Tags block to tag courses in a course
When I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add the "Tags" block
And I log out
And I log in as "student1"
And I follow "Course 1"
And I should not see "Neverusedtag" in the "Tags" "block"
And I click on "more..." "link" in the "Tags" "block"
And I should not see "Neverusedtag"
And I follow "c1"
And I set the field "coursetag_new_tag" to "Dogs, Mice"
And I press "Add"
And I should see "Dogs" in the "Tags" "block"
And I should see "Mice" in the "Tags" "block"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I should see "Dogs" in the "Tags" "block"
And I set the field "coursetag_new_tag" to "Cats, Dogs"
And I press "Add"
And I should see "Dogs" in the "Tags" "block"
And I should see "Cats" in the "Tags" "block"
And I click on "more..." "link" in the "Tags" "block"
And "Cats" "link" should appear before "Dogs" "link"
And "Dogs" "link" should appear before "Mice" "link"
And I follow "My tags"
And I should see "Dogs"
And I should see "Cats"
And I should not see "Mice"
And I follow "All tags"
And I follow "Popularity"
And "Mice" "link" should appear before "Dogs" "link"
And I should not see "Neverusedtag"
And I log out
+6
View File
@@ -122,6 +122,12 @@ if (!empty($course)) {
$course->{'role_'.$alias->roleid} = $alias->name;
}
// Populate course tags.
if (!empty($CFG->usetags)) {
include_once($CFG->dirroot.'/tag/lib.php');
$course->tags = tag_get_tags_array('course', $course->id);
}
} else {
// Editor should respect category context if course context is not set.
$editoroptions['context'] = $catcontext;
+7
View File
@@ -301,6 +301,13 @@ class course_edit_form extends moodleform {
}
}
if (!empty($CFG->usetags) &&
((empty($course->id) && guess_if_creator_will_have_course_capability('moodle/course:tag', $categorycontext))
|| (!empty($course->id) && has_capability('moodle/course:tag', $coursecontext)))) {
$mform->addElement('header', 'tagshdr', get_string('tags', 'tag'));
$mform->addElement('tags', 'tags', get_string('tags'));
}
// When two elements we need a group.
$buttonarray = array();
if ($returnto !== 0) {
+12 -2
View File
@@ -2547,7 +2547,7 @@ function course_overviewfiles_options($course) {
* @return object new course instance
*/
function create_course($data, $editoroptions = NULL) {
global $DB;
global $DB, $CFG;
//check the categoryid - must be given for all new courses
$category = $DB->get_record('course_categories', array('id'=>$data->category), '*', MUST_EXIST);
@@ -2623,6 +2623,11 @@ function create_course($data, $editoroptions = NULL) {
// set up enrolments
enrol_course_updated(true, $course, $data);
// Update course tags.
if ($CFG->usetags && isset($data->tags)) {
tag_set('course', $course->id, $data->tags, 'core', context_course::instance($course->id)->id);
}
// Trigger a course created event.
$event = \core\event\course_created::create(array(
'objectid' => $course->id,
@@ -2646,7 +2651,7 @@ function create_course($data, $editoroptions = NULL) {
* @return void
*/
function update_course($data, $editoroptions = NULL) {
global $DB;
global $DB, $CFG;
$data->timemodified = time();
@@ -2733,6 +2738,11 @@ function update_course($data, $editoroptions = NULL) {
// update enrol settings
enrol_course_updated(false, $course, $data);
// Update course tags.
if ($CFG->usetags && isset($data->tags)) {
tag_set('course', $course->id, $data->tags, 'core', context_course::instance($course->id)->id);
}
// Trigger a course updated event.
$event = \core\event\course_updated::create(array(
'objectid' => $course->id,
+68
View File
@@ -0,0 +1,68 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Edit course tags
*
* @package core_course
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once("../config.php");
require_once($CFG->dirroot . '/tag/lib.php');
require_once($CFG->dirroot . '/course/tags_form.php');
$id = required_param('id', PARAM_INT); // Course id.
$returnurl = optional_param('return', null, PARAM_LOCALURL);
$course = get_course($id);
require_login();
// Check capabilities but do not call require_login($course) - the user does not have to be enrolled.
$context = context_course::instance($course->id);
if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
print_error('coursehidden', '', $CFG->wwwroot .'/');
}
require_capability('moodle/course:tag', $context);
if (empty($CFG->usetags)) {
print_error('tagsaredisabled', 'tag');
}
$PAGE->set_course($course);
$PAGE->set_pagelayout('incourse');
$PAGE->set_url('/course/tags.php', array('id' => $course->id));
$PAGE->set_title(get_string('coursetags', 'tag'));
$PAGE->set_heading($course->fullname);
$form = new coursetags_form();
$data = array('id' => $course->id, 'tags' => tag_get_tags_array('course', $course->id));
$form->set_data($data);
$redirecturl = $returnurl ? new moodle_url($returnurl) : course_get_url($course);
if ($form->is_cancelled()) {
redirect($redirecturl);
} else if ($data = $form->get_data()) {
tag_set('course', $course->id, $data->tags, 'core', context_course::instance($course->id)->id);
redirect($redirecturl);
}
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('coursetags', 'tag'));
$form->display();
echo $OUTPUT->footer();
+52
View File
@@ -0,0 +1,52 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Edit course tags form
*
* @package core_course
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
/**
* Edit course tags form
*
* @package core_course
* @copyright 2015 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class coursetags_form extends moodleform {
/**
* Form definition
*/
public function definition() {
$mform = $this->_form;
$mform->addElement('tags', 'tags', get_string('tags'));
$mform->addElement('hidden', 'id', null);
$mform->setType('id', PARAM_INT);
$this->add_action_buttons();
}
}
+98
View File
@@ -0,0 +1,98 @@
@core @core_course @core_tag
Feature: Tagging courses
In order to search courses
As a teacher
I need to be able to tag courses
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| teacher2 | Teacher | 2 | teacher2@example.com |
| user1 | User | 1 | user1@example.com |
And the following "courses" exist:
| fullname | shortname |
| Course 1 | c1 |
| Course 2 | c2 |
And the following "tags" exist:
| name | tagtype |
| Neverusedtag | official |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | c1 | editingteacher |
| teacher2 | c1 | teacher |
| teacher1 | c2 | editingteacher |
| teacher2 | c2 | teacher |
And I log in as "teacher1"
And I follow "Course 1"
And I click on "Edit settings" "link" in the "Administration" "block"
And I set the following fields to these values:
| Other tags (enter tags separated by commas) | Mathematics |
And I press "Save and display"
And I log out
Scenario: Set course tags using the course edit form
When I log in as "teacher1"
And I follow "Course 1"
And "Course tags" "link" should not exist in the "Administration" "block"
And I click on "Edit settings" "link" in the "Administration" "block"
And the field "Other tags (enter tags separated by commas)" matches value "Mathematics"
And I set the following fields to these values:
| Other tags (enter tags separated by commas) | Mathematics, Algebra |
And I press "Save and display"
And I click on "Dashboard" "link" in the "Navigation" "block"
And I follow "Course 2"
And I click on "Edit settings" "link" in the "Administration" "block"
And I set the following fields to these values:
| Other tags (enter tags separated by commas) | Mathematics, Geometry |
And I press "Save and display"
And I log out
And I log in as "user1"
And I navigate to "Tags" node in "Site pages"
And I follow "Mathematics"
Then I should see "Course 1"
And I should see "Course 2"
And I follow "Tags"
And I follow "Algebra"
And I should see "Course 1"
And I should not see "Course 2"
And I follow "Tags"
And I follow "Geometry"
And I should not see "Course 1"
And I should see "Course 2"
And I log out
Scenario: User can set course tags using separate form
Given I log in as "admin"
And I set the following system permissions of "Non-editing teacher" role:
| moodle/course:tag | Allow |
And I log out
When I log in as "teacher2"
And I follow "Course 1"
And "Edit settings" "link" should not exist in the "Administration" "block"
And I click on "Course tags" "link" in the "Administration" "block"
And the field "Other tags (enter tags separated by commas)" matches value "Mathematics"
And I set the following fields to these values:
| Other tags (enter tags separated by commas) | Mathematics, Algebra |
And I press "Save changes"
And I click on "Dashboard" "link" in the "Navigation" "block"
And I follow "Course 2"
And I click on "Course tags" "link" in the "Administration" "block"
And I set the following fields to these values:
| Other tags (enter tags separated by commas) | Mathematics, Geometry |
And I press "Save changes"
And I log out
And I log in as "user1"
And I navigate to "Tags" node in "Site pages"
And I follow "Mathematics"
Then I should see "Course 1"
And I should see "Course 2"
And I follow "Tags"
And I follow "Algebra"
And I should see "Course 1"
And I should not see "Course 2"
And I follow "Tags"
And I follow "Geometry"
And I should not see "Course 1"
And I should see "Course 2"
And I log out
+1
View File
@@ -18,3 +18,4 @@ tagtype_official,core_tag
thistaghasnodesc,core_tag
updated,core_tag
withselectedtags,core_tag
tag:create,core_role
+4 -1
View File
@@ -146,6 +146,7 @@ $string['course:reset'] = 'Reset course';
$string['course:reviewotherusers'] = 'Review other users';
$string['course:sectionvisibility'] = 'Control section visibility';
$string['course:setcurrentsection'] = 'Set current section';
$string['course:tag'] = 'Change course tags';
$string['course:update'] = 'Update course settings';
$string['course:useremail'] = 'Enable/disable email address';
$string['course:view'] = 'View courses without participation';
@@ -373,7 +374,6 @@ $string['site:viewfullnames'] = 'Always see full names of users';
$string['site:viewparticipants'] = 'View participants';
$string['site:viewreports'] = 'View reports';
$string['site:viewuseridentity'] = 'See full user identity in lists';
$string['tag:create'] = 'Create new tags';
$string['tag:edit'] = 'Edit existing tags';
$string['tag:editblocks'] = 'Edit blocks in tags pages';
$string['tag:manage'] = 'Manage all tags';
@@ -424,3 +424,6 @@ $string['whydoesusernothavecap'] = 'Why does {$a->fullname} not have capability
$string['xroleassignments'] = '{$a}\'s role assignments';
$string['xuserswiththerole'] = 'Users with the role "{$a->role}"';
// Deprecated in 3.0.
$string['tag:create'] = 'Create new tags';
+1
View File
@@ -29,6 +29,7 @@ $string['alltagpages'] = 'All tag pages';
$string['confirmdeletetag'] = 'Are you sure you want to delete this tag?';
$string['confirmdeletetags'] = 'Are you sure you want to delete selected tags?';
$string['count'] = 'Count';
$string['coursetags'] = 'Course tags';
$string['delete'] = 'Delete';
$string['deleteselected'] = 'Delete selected';
$string['deleted'] = 'Tag(s) deleted';
+11 -14
View File
@@ -1090,6 +1090,17 @@ $capabilities = array(
)
),
'moodle/course:tag' => array(
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
),
'clonepermissionsfrom' => 'moodle/course:update'
),
'moodle/blog:view' => array(
'captype' => 'read',
@@ -1697,23 +1708,10 @@ $capabilities = array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
)
),
'moodle/tag:create' => array(
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'user' => CAP_ALLOW
)
),
'moodle/tag:edit' => array(
'riskbitmask' => RISK_SPAM,
@@ -1730,7 +1728,6 @@ $capabilities = array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'user' => CAP_ALLOW
)
),
-1
View File
@@ -1972,7 +1972,6 @@
</KEYS>
<INDEXES>
<INDEX NAME="name" UNIQUE="true" FIELDS="name" COMMENT="tag names are unique"/>
<INDEX NAME="idname" UNIQUE="true" FIELDS="id, name" COMMENT="Improves performance of autocomplete in tag block"/>
</INDEXES>
</TABLE>
<TABLE NAME="tag_correlation" COMMENT="The rationale for the 'tag_correlation' table is performance. It works as a cache for a potentially heavy load query done at the 'tag_instance' table. So, the 'tag_correlation' table stores redundant information derived from the 'tag_instance' table">
+28
View File
@@ -4530,5 +4530,33 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2015090200.00);
}
if ($oldversion < 2015090801.00) {
// This upgrade script merges all tag instances pointing to the same course tag.
// User id is no longer used for those tag instances.
upgrade_course_tags();
// If configuration variable "Show course tags" is set, disable the block
// 'tags' because it can not be used for tagging courses any more.
if (!empty($CFG->block_tags_showcoursetags)) {
if ($record = $DB->get_record('block', array('name' => 'tags'), 'id, visible')) {
if ($record->visible) {
$DB->update_record('block', array('id' => $record->id, 'visible' => 0));
}
}
}
// Define index idname (unique) to be dropped form tag (it's really weird).
$table = new xmldb_table('tag');
$index = new xmldb_index('idname', XMLDB_INDEX_UNIQUE, array('id', 'name'));
// Conditionally launch drop index idname.
if ($dbman->index_exists($table, $index)) {
$dbman->drop_index($table, $index);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2015090801.00);
}
return true;
}
+21 -1
View File
@@ -667,4 +667,24 @@ function upgrade_calculated_grade_items($courseid = null) {
}
}
}
}
}
/**
* This upgrade script merges all tag instances pointing to the same course tag
*
* User id is no longer used for those tag instances
*/
function upgrade_course_tags() {
global $DB;
$sql = "SELECT min(ti.id)
FROM {tag_instance} ti
LEFT JOIN {tag_instance} tii on tii.itemtype = ? and tii.itemid = ti.itemid and tii.tiuserid = 0 and tii.tagid = ti.tagid
where ti.itemtype = ? and ti.tiuserid <> 0 AND tii.id is null
group by ti.tagid, ti.itemid";
$ids = $DB->get_fieldset_sql($sql, array('course', 'course'));
if ($ids) {
list($idsql, $idparams) = $DB->get_in_or_equal($ids);
$DB->execute('UPDATE {tag_instance} SET tiuserid = 0 WHERE id ' . $idsql, $idparams);
}
$DB->execute("DELETE FROM {tag_instance} WHERE itemtype = ? AND tiuserid <> 0", array('course'));
}
+304
View File
@@ -2419,3 +2419,307 @@ function completion_cron() {
completion_cron_completions();
}
/**
* Returns an ordered array of tags associated with visible courses
* (boosted replacement of get_all_tags() allowing association with user and tagtype).
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @param int $courseid A course id. Passing 0 will return all distinct tags for all visible courses
* @param int $userid (optional) the user id, a default of 0 will return all users tags for the course
* @param string $tagtype (optional) The type of tag, empty string returns all types. Currently (Moodle 2.2) there are two
* types of tags which are used within Moodle, they are 'official' and 'default'.
* @param int $numtags (optional) number of tags to display, default of 80 is set in the block, 0 returns all
* @param string $unused (optional) was selected sorting, moved to tag_print_cloud()
* @return array
*/
function coursetag_get_tags($courseid, $userid=0, $tagtype='', $numtags=0, $unused = '') {
debugging('Function coursetag_get_tags() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
global $CFG, $DB;
// get visible course ids
$courselist = array();
if ($courseid === 0) {
if ($courses = $DB->get_records_select('course', 'visible=1 AND category>0', null, '', 'id')) {
foreach ($courses as $key => $value) {
$courselist[] = $key;
}
}
}
// get tags from the db ordered by highest count first
$params = array();
$sql = "SELECT id as tkey, name, id, tagtype, rawname, f.timemodified, flag, count
FROM {tag} t,
(SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count
FROM {tag_instance}
WHERE itemtype = 'course' ";
if ($courseid > 0) {
$sql .= " AND itemid = :courseid ";
$params['courseid'] = $courseid;
} else {
if (!empty($courselist)) {
list($usql, $uparams) = $DB->get_in_or_equal($courselist, SQL_PARAMS_NAMED);
$sql .= "AND itemid $usql ";
$params = $params + $uparams;
}
}
if ($userid > 0) {
$sql .= " AND tiuserid = :userid ";
$params['userid'] = $userid;
}
$sql .= " GROUP BY tagid) f
WHERE t.id = f.tagid ";
if ($tagtype != '') {
$sql .= "AND tagtype = :tagtype ";
$params['tagtype'] = $tagtype;
}
$sql .= "ORDER BY count DESC, name ASC";
// limit the number of tags for output
if ($numtags == 0) {
$tags = $DB->get_records_sql($sql, $params);
} else {
$tags = $DB->get_records_sql($sql, $params, 0, $numtags);
}
// prepare the return
$return = array();
if ($tags) {
// avoid print_tag_cloud()'s ksort upsetting ordering by setting the key here
foreach ($tags as $value) {
$return[] = $value;
}
}
return $return;
}
/**
* Returns an ordered array of tags
* (replaces popular_tags_count() allowing sorting).
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @param string $unused (optional) was selected sorting - moved to tag_print_cloud()
* @param int $numtags (optional) number of tags to display, default of 20 is set in the block, 0 returns all
* @return array
*/
function coursetag_get_all_tags($unused='', $numtags=0) {
debugging('Function coursetag_get_all_tag() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
global $CFG, $DB;
// note that this selects all tags except for courses that are not visible
$sql = "SELECT id, name, tagtype, rawname, f.timemodified, flag, count
FROM {tag} t,
(SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count
FROM {tag_instance} WHERE tagid NOT IN
(SELECT tagid FROM {tag_instance} ti, {course} c
WHERE c.visible = 0
AND ti.itemtype = 'course'
AND ti.itemid = c.id)
GROUP BY tagid) f
WHERE t.id = f.tagid
ORDER BY count DESC, name ASC";
if ($numtags == 0) {
$tags = $DB->get_records_sql($sql);
} else {
$tags = $DB->get_records_sql($sql, null, 0, $numtags);
}
$return = array();
if ($tags) {
foreach ($tags as $value) {
$return[] = $value;
}
}
return $return;
}
/**
* Returns javascript for use in tags block and supporting pages
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @return null
*/
function coursetag_get_jscript() {
debugging('Function coursetag_get_jscript() is deprecated and obsolete.', DEBUG_DEVELOPER);
return '';
}
/**
* Returns javascript to create the links in the tag block footer.
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @param string $elementid the element to attach the footer to
* @param array $coursetagslinks links arrays each consisting of 'title', 'onclick' and 'text' elements
* @return string always returns a blank string
*/
function coursetag_get_jscript_links($elementid, $coursetagslinks) {
debugging('Function coursetag_get_jscript_links() is deprecated and obsolete.', DEBUG_DEVELOPER);
return '';
}
/**
* Returns all tags created by a user for a course
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @param int $courseid tags are returned for the course that has this courseid
* @param int $userid return tags which were created by this user
*/
function coursetag_get_records($courseid, $userid) {
debugging('Function coursetag_get_records() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
global $CFG, $DB;
$sql = "SELECT t.id, name, rawname
FROM {tag} t, {tag_instance} ti
WHERE t.id = ti.tagid
AND ti.tiuserid = :userid
AND ti.itemid = :courseid
ORDER BY name ASC";
return $DB->get_records_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid));
}
/**
* Stores a tag for a course for a user
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @param array $tags simple array of keywords to be stored
* @param int $courseid the id of the course we wish to store a tag for
* @param int $userid the id of the user we wish to store a tag for
* @param string $tagtype official or default only
* @param string $myurl (optional) for logging creation of course tags
*/
function coursetag_store_keywords($tags, $courseid, $userid=0, $tagtype='official', $myurl='') {
debugging('Function coursetag_store_keywords() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
global $CFG;
require_once $CFG->dirroot.'/tag/lib.php';
if (is_array($tags) and !empty($tags)) {
foreach ($tags as $tag) {
$tag = trim($tag);
if (strlen($tag) > 0) {
//tag_set_add('course', $courseid, $tag, $userid); //deletes official tags
//add tag if does not exist
if (!$tagid = tag_get_id($tag)) {
$tag_id_array = tag_add(array($tag), $tagtype);
$tagid = $tag_id_array[core_text::strtolower($tag)];
}
//ordering
$ordering = 0;
if ($current_ids = tag_get_tags_ids('course', $courseid)) {
end($current_ids);
$ordering = key($current_ids) + 1;
}
//set type
tag_type_set($tagid, $tagtype);
//tag_instance entry
tag_assign('course', $courseid, $tagid, $ordering, $userid, 'core', context_course::instance($courseid)->id);
}
}
}
}
/**
* Deletes a personal tag for a user for a course.
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @param int $tagid the tag we wish to delete
* @param int $userid the user that the tag is associated with
* @param int $courseid the course that the tag is associated with
*/
function coursetag_delete_keyword($tagid, $userid, $courseid) {
debugging('Function coursetag_delete_keyword() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
tag_delete_instance('course', $courseid, $tagid, $userid);
}
/**
* Get courses tagged with a tag
*
* @deprecated since 3.0
* @package core_tag
* @category tag
* @param int $tagid
* @return array of course objects
*/
function coursetag_get_tagged_courses($tagid) {
debugging('Function coursetag_get_tagged_courses() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
global $DB;
$courses = array();
$ctxselect = context_helper::get_preload_record_columns_sql('ctx');
$sql = "SELECT c.*, $ctxselect
FROM {course} c
JOIN {tag_instance} t ON t.itemid = c.id
JOIN {context} ctx ON ctx.instanceid = c.id
WHERE t.tagid = :tagid AND
t.itemtype = 'course' AND
ctx.contextlevel = :contextlevel
ORDER BY c.sortorder ASC";
$params = array('tagid' => $tagid, 'contextlevel' => CONTEXT_COURSE);
$rs = $DB->get_recordset_sql($sql, $params);
foreach ($rs as $course) {
context_helper::preload_from_record($course);
if ($course->visible == 1 || has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) {
$courses[$course->id] = $course;
}
}
return $courses;
}
/**
* Course tagging function used only during the deletion of a course (called by lib/moodlelib.php) to clean up associated tags
*
* @package core_tag
* @deprecated since 3.0
* @param int $courseid the course we wish to delete tag instances from
* @param bool $showfeedback if we should output a notification of the delete to the end user
*/
function coursetag_delete_course_tags($courseid, $showfeedback=false) {
debugging('Function coursetag_delete_course_tags() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER);
global $DB, $OUTPUT;
if ($taginstances = $DB->get_recordset_select('tag_instance', "itemtype = 'course' AND itemid = :courseid",
array('courseid' => $courseid), '', 'tagid, tiuserid')) {
foreach ($taginstances as $record) {
tag_delete_instance('course', $courseid, $record->tagid, $record->tiuserid);
}
$taginstances->close();
}
if ($showfeedback) {
echo $OUTPUT->notification(get_string('deletedcoursetags', 'tag'), 'notifysuccess');
}
}
+2 -2
View File
@@ -4736,7 +4736,7 @@ function remove_course_contents($courseid, $showfeedback = true, array $options
require_once($CFG->libdir.'/questionlib.php');
require_once($CFG->libdir.'/gradelib.php');
require_once($CFG->dirroot.'/group/lib.php');
require_once($CFG->dirroot.'/tag/coursetagslib.php');
require_once($CFG->dirroot.'/tag/lib.php');
require_once($CFG->dirroot.'/comment/lib.php');
require_once($CFG->dirroot.'/rating/lib.php');
require_once($CFG->dirroot.'/notes/lib.php');
@@ -4911,7 +4911,7 @@ function remove_course_contents($courseid, $showfeedback = true, array $options
$rm->delete_ratings($delopt);
// Delete course tags.
coursetag_delete_course_tags($course->id, $showfeedback);
tag_set('course', $course->id, array(), 'core', $coursecontext->id);
// Delete calendar events.
$DB->delete_records('event', array('courseid' => $course->id));
+3
View File
@@ -3763,6 +3763,9 @@ class settings_navigation extends navigation_node {
$url = new moodle_url('/course/completion.php', array('id'=>$course->id));
$coursenode->add(get_string('coursecompletion', 'completion'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', ''));
}
} else if (has_capability('moodle/course:tag', $coursecontext)) {
$url = new moodle_url('/course/tags.php', array('id' => $course->id));
$coursenode->add(get_string('coursetags', 'tag'), $url, self::TYPE_SETTING, null, 'coursetags', new pix_icon('i/settings', ''));
}
// add enrol nodes
+58
View File
@@ -741,4 +741,62 @@ class core_upgradelib_testcase extends advanced_testcase {
$this->assertEquals($gradecategoryitem->grademax, $grade->rawgrademax);
$this->assertEquals($gradecategoryitem->grademin, $grade->rawgrademin);
}
public function test_upgrade_course_tags() {
global $DB;
$this->resetAfterTest();
// Running upgrade script when there are no tags.
upgrade_course_tags();
$this->assertFalse($DB->record_exists('tag_instance', array()));
// No course entries.
$DB->insert_record('tag_instance', array('itemid' => 123, 'tagid' => 101, 'tiuserid' => 0,
'itemtype' => 'post', 'component' => 'core', 'contextid' => 1));
$DB->insert_record('tag_instance', array('itemid' => 333, 'tagid' => 103, 'tiuserid' => 1002,
'itemtype' => 'post', 'component' => 'core', 'contextid' => 1));
upgrade_course_tags();
$records = array_values($DB->get_records('tag_instance', array(), 'id', '*'));
$this->assertEquals(2, count($records));
$this->assertEquals(123, $records[0]->itemid);
$this->assertEquals(333, $records[1]->itemid);
// Imagine we have tags 101, 102, 103, ... and courses 1, 2, 3, ... and users 1001, 1002, ... .
$keys = array('itemid', 'tagid', 'tiuserid');
$valuesets = array(
array(1, 101, 0),
array(1, 102, 0),
array(2, 102, 0),
array(2, 103, 1001),
array(3, 103, 0),
array(3, 103, 1001),
array(3, 104, 1006),
array(3, 104, 1001),
array(3, 104, 1002),
);
foreach ($valuesets as $values) {
$DB->insert_record('tag_instance', array_combine($keys, $values) +
array('itemtype' => 'course', 'component' => 'core', 'contextid' => 1));
}
upgrade_course_tags();
// There are 8 records in 'tag_instance' table and 7 of them do not have tiuserid (except for one 'post').
$records = array_values($DB->get_records('tag_instance', array(), 'id', '*'));
$this->assertEquals(8, count($records));
$this->assertEquals(7, $DB->count_records('tag_instance', array('tiuserid' => 0)));
// Course 1 is mapped to tags 101 and 102.
$this->assertEquals(array(101, 102), array_values($DB->get_fieldset_select('tag_instance', 'tagid',
'itemtype = ? AND itemid = ? ORDER BY tagid', array('course', 1))));
// Course 2 is mapped to tags 102 and 103.
$this->assertEquals(array(102, 103), array_values($DB->get_fieldset_select('tag_instance', 'tagid',
'itemtype = ? AND itemid = ? ORDER BY tagid', array('course', 2))));
// Course 1 is mapped to tags 101 and 102.
$this->assertEquals(array(103, 104), array_values($DB->get_fieldset_select('tag_instance', 'tagid',
'itemtype = ? AND itemid = ? ORDER BY tagid', array('course', 3))));
}
}
+1
View File
@@ -373,6 +373,7 @@ function upgrade_stale_php_files_present() {
$someexamplesofremovedfiles = array(
// Removed in 3.0.
'/mod/lti/grade.php',
'/tag/coursetagslib.php',
// Removed in 2.9.
'/lib/timezone.txt',
// Removed in 2.8.
-62
View File
@@ -1,62 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* coursetags_add.php
*
* @package core_tag
* @category tag
* @copyright 2007 [email protected]
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_login();
$systemcontext = context_system::instance();
require_capability('moodle/tag:create', $systemcontext);
if (empty($CFG->usetags)) {
print_error('tagsaredisabled', 'tag');
}
$returnurl = optional_param('returnurl', null, PARAM_LOCALURL);
$keyword = optional_param('coursetag_new_tag', '', PARAM_TEXT);
$courseid = optional_param('entryid', 0, PARAM_INT);
$userid = optional_param('userid', 0, PARAM_INT);
$keyword = trim(strip_tags($keyword));
if ($keyword and confirm_sesskey()) {
require_once($CFG->dirroot.'/tag/coursetagslib.php');
if ($courseid > 0 and $userid > 0) {
$myurl = 'tag/search.php';
$keywords = explode(',', $keyword);
coursetag_store_keywords($keywords, $courseid, $userid, 'default', $myurl);
}
}
// send back to originating page, where the new tag will be visible in the block
if ($returnurl) {
redirect($returnurl);
} else {
$myurl = $CFG->wwwroot.'/';
}
redirect($myurl);
-217
View File
@@ -1,217 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Displays personal tags for a course with some editing facilites
*
* @package core_tag
* @category tag
* @copyright 2007 [email protected]
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->dirroot.'/tag/coursetagslib.php');
require_once($CFG->dirroot.'/tag/lib.php');
$courseid = optional_param('courseid', 0, PARAM_INT);
$keyword = optional_param('coursetag_new_tag', '', PARAM_TEXT);
$deltag = optional_param('del_tag', 0, PARAM_INT);
$url = new moodle_url('/tag/coursetags_edit.php');
if ($courseid !== 0) {
$url->param('courseid', $courseid);
}
if ($keyword !== '') {
$url->param('coursetag_new_tag', $keyword);
}
if ($deltag !== 0) {
$url->param('del_tag', $deltag);
}
$PAGE->set_url($url);
require_login();
if (empty($CFG->usetags)) {
print_error('tagsaredisabled', 'tag');
}
if ($courseid != SITEID) {
if (! ($course = $DB->get_record('course', array('id' => $courseid), '*')) ) {
print_error('invalidcourse');
}
} else {
print_error('errortagfrontpage', 'tag');
}
// Permissions
$sitecontext = context_system::instance();
require_login($course);
$canedit = has_capability('moodle/tag:create', $sitecontext);
// Language strings
$tagslang = 'block_tags';
// Store data
if ($data = data_submitted()) {
if (confirm_sesskey() and $courseid > 0 and $USER->id > 0 and $canedit) {
// store personal tag
if (trim(strip_tags($keyword))) {
$myurl = 'tag/search.php';
$keywords = explode(',', $keyword);
coursetag_store_keywords($keywords, $courseid, $USER->id, 'default', $myurl);
}
// delete personal tag
if ($deltag > 0) {
coursetag_delete_keyword($deltag, $USER->id, $courseid);
}
}
}
// The title and breadcrumb
$title = get_string('edittitle', $tagslang);
$coursefullname = format_string($course->fullname);
$courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
$PAGE->navbar->add($title);
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
$PAGE->set_cacheable(false);
echo $OUTPUT->header();
// Print personal tags for all courses
$title = get_string('edittitle', $tagslang);
echo $OUTPUT->heading($title, 2, 'mdl-align');
$mytags = tag_print_cloud(coursetag_get_tags(0, $USER->id, 'default'), 150, true);
$outstr = '
<div class="coursetag_edit_centered">
<div>
'.get_string('editmytags', $tagslang).'
</div>
<div>';
if ($mytags) {
$outstr .= $mytags;
} else {
$outstr .= get_string('editnopersonaltags', $tagslang);
}
$outstr .= '
</div>
</div>';
echo $outstr;
// Personal tag editing
if ($canedit) {
$title = get_string('editmytagsfor', $tagslang, '"'.$coursefullname.' ('.$courseshortname.')"');
echo $OUTPUT->heading($title, 2, 'main mdl-align');
// Deletion here is open to the users own tags for this course only
$selectoptions = '<option value="0">'.get_string('select', $tagslang).'</option>';
$coursetabs = '';
if ($options = coursetag_get_records($courseid, $USER->id)) {
$coursetabs = '"';
foreach ($options as $option) {
$selectoptions .= '<option value="'.$option->id.'">'.$option->rawname.'</option>';
$coursetabs .= $option->rawname . ', ';
}
$coursetabs = rtrim($coursetabs, ', ');
$coursetabs .= '"';
}
if ($coursetabs) {
$outstr = '
<div class="coursetag_edit_centered">
'.get_string('editthiscoursetags', $tagslang, $coursetabs).'
</div>';
} else {
$outstr = '
<div class="coursetag_edit_centered">
'.get_string('editnopersonaltags', $tagslang).'
</div>';
}
// Print the add and delete form
coursetag_get_jscript();
$edittagthisunit = get_string('edittagthisunit', $tagslang);
$suggestedtagthisunit = get_string('suggestedtagthisunit', $tagslang);
$arrowtitle = get_string('arrowtitle', $tagslang);
$sesskey = sesskey();
$leftarrow = $OUTPUT->pix_url('t/arrow_left');
$outstr .= <<<EOT
<form action="$CFG->wwwroot/tag/coursetags_edit.php" method="post" id="coursetag">
<div style="display: none;">
<input type="hidden" name="courseid" value="$course->id" />
<input type="hidden" name="sesskey" value="$sesskey" />
</div>
<div class="coursetag_edit_centered">
<div class="coursetag_edit_row">
<div class="coursetag_edit_left">
<label class="accesshide" for="coursetag_sug_keyword">$suggestedtagthisunit</label>
</div>
<div class="coursetag_edit_right">
<div class="coursetag_form_input1">
<input type="text" name="coursetag_sug_keyword" id="coursetag_sug_keyword" class="coursetag_form_input1a" disabled="disabled" />
</div>
</div>
</div>
<div class="coursetag_edit_row">
<div class="coursetag_edit_left">
<label for="coursetag_new_tag">$edittagthisunit</label>
</div>
<div class="coursetag_edit_right">
<div class="coursetag_form_input2">
<input type="text" name="coursetag_new_tag" id="coursetag_new_tag" class="coursetag_form_input2a"
onfocus="ctags_getKeywords()" onkeyup="ctags_getKeywords()" maxlength="50" />
</div>
<div class="coursetag_edit_input3" id="coursetag_sug_btn">
<a title="$arrowtitle">
<img src="$leftarrow" width="10" height="10" alt="enter" onclick="ctags_setKeywords()" />
</a>
</div>
</div>
</div>
EOT;
if ($coursetabs) {
$editdeletemytag = get_string('editdeletemytag', $tagslang);
$outstr .= <<<EOT1
<div class="coursetag_edit_row">
<div class="coursetag_edit_left">
<label for="del_tag">
$editdeletemytag
</label>
</div>
<div class="coursetag_edit_right">
<select id="del_tag" name="del_tag">
$selectoptions
</select>
</div>
</div>
EOT1;
}
$submitstr = get_string('submit');
$outstr .= <<<EOT2
<div class="clearer"></div>
<div class="coursetag_edit_row">
<button type="submit">$submitstr</button>
</div>
</div>
</form>
EOT2;
echo $outstr;
}
echo $OUTPUT->footer();
-184
View File
@@ -1,184 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A full display of tags allowing some filtering and reordering
*
* @package core_tag
* @category tag
* @copyright 2007 [email protected]
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->dirroot.'/tag/coursetagslib.php');
require_once($CFG->dirroot.'/tag/lib.php');
$sort = optional_param('sort', 'alpha', PARAM_ALPHA); //alpha, date or popularity
$show = optional_param('show', 'all', PARAM_ALPHA); //all, my, official, community or course
$courseid = optional_param('courseid', 0, PARAM_INT);
$url = new moodle_url('/tag/coursetags_more.php');
if ($sort !== 'alpha') {
$url->param('sort', $sort);
}
if ($show !== 'all') {
$url->param('show', $show);
}
if ($courseid !== 0) {
$url->param('courseid', $courseid);
}
$PAGE->set_url($url);
if (empty($CFG->usetags)) {
print_error('tagsaredisabled', 'tag');
}
// Some things require logging in
if ($CFG->forcelogin or $show == 'my') {
require_login();
}
// Permissions
$loggedin = isloggedin() && !isguestuser();
// Course check
if ($courseid) {
if (!($course = $DB->get_record('course', array('id'=>$courseid)))) {
$courseid = 0;
}
if ($courseid == SITEID) $courseid = 0;
}
if ($courseid) {
$PAGE->set_context(context_course::instance($courseid));
} else {
$PAGE->set_context(context_system::instance());
}
// Language strings
$tagslang = 'block_tags';
$title = get_string('moretitle', $tagslang);
$link1 = get_string('moreshow', $tagslang);
$link2 = get_string('moreorder', $tagslang);
$showalltags = get_string('moreshowalltags', $tagslang);
$showofficialtags = get_string('moreshowofficialtags', $tagslang);
$showmytags = get_string('moreshowmytags', $tagslang);
$showcommtags = get_string('moreshowcommtags', $tagslang);
$orderalpha = get_string('moreorderalpha', $tagslang);
$orderdate = get_string('moreorderdate', $tagslang);
$orderpop = get_string('moreorderpop', $tagslang);
$welcome = get_string('morewelcome', $tagslang);
// The title and breadcrumb
if ($courseid) {
$courseshortname = format_string($course->shortname, true, array('context' => context_course::instance($courseid)));
$PAGE->navbar->add($courseshortname, new moodle_url('/course/view.php', array('id'=>$courseid)));
}
$PAGE->navbar->add($title);
$PAGE->set_title($title);
$PAGE->set_heading($COURSE->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading($title, 2, 'centre');
// Prepare data for tags
$courselink = '';
if ($courseid) {
$courselink = '&amp;courseid='.$courseid;
}
$myurl = $CFG->wwwroot.'/tag/coursetags_more.php';
$myurl2 = $CFG->wwwroot.'/tag/coursetags_more.php?show='.$show;
if ($show == 'course' and $courseid) { // Course tags.
$tags = tag_print_cloud(coursetag_get_tags($courseid, 0, ''), 150, true, $sort);
} else if ($show == 'my' and $loggedin) { // My tags.
$tags = tag_print_cloud(coursetag_get_tags(0, $USER->id, 'default'), 150, true, $sort);
} else if ($show == 'official') { // Official course tags.
$tags = tag_print_cloud(coursetag_get_tags(0, 0, 'official'), 150, true, $sort);
} else if ($show == 'community') { // Community (official and personal together) also called user tags.
$tags = tag_print_cloud(coursetag_get_tags(0, 0, 'default'), 150, true, $sort);
} else {
// All tags for courses and blogs and any thing else tagged - the fallback default ($show == all).
$subtitle = $showalltags;
$tags = tag_print_cloud(coursetag_get_all_tags(), 150, true, $sort);
}
// Prepare the links for the show and order lines
if ($show == 'all') {
$link1 .= '<b>'.$showalltags.'</b>';
} else {
$link1 .= '<a href="'.$myurl.'?show=all'.$courselink.'">'.$showalltags.'</a>';
}
//if ($show == 'official') { //add back in if you start to use official course tags
// $link1 .= ' | <b>'.$showofficialtags.'</b>';
//} else {
// $link1 .= ' | <a href="'.$myurl.'?show=official'.$courselink.'">'.$showofficialtags.'</a>';
//}
if ($show == 'community') {
$link1 .= ' | <b>'.$showcommtags.'</b>';
} else {
$link1 .= ' | <a href="'.$myurl.'?show=community'.$courselink.'">'.$showcommtags.'</a>';
}
if ($loggedin) {
if ($show == 'my') {
$link1 .= ' | <b>'.$showmytags.'</b>';
} else {
$link1 .= ' | <a href="'.$myurl.'?show=my'.$courselink.'">'.$showmytags.'</a>';
}
}
if ($courseid) {
$fullname = format_string($course->fullname, true, array('context' => context_course::instance($course->id)));
if ($show == 'course') {
$link1 .= ' | <b>'.get_string('moreshowcoursetags', $tagslang, $fullname).'</b>';
} else {
$link1 .= ' | <a href="'.$myurl.'?show=course'.$courselink.'">'.get_string('moreshowcoursetags', $tagslang, $fullname).'</a>';
}
}
if ($sort == 'alpha') {
$link2 .= '<b>'.$orderalpha.'</b> | ';
} else {
$link2 .= '<a href="'.$myurl2.'&amp;sort=alpha'.$courselink.'">'.$orderalpha.'</a> | ';
}
if ($sort == 'popularity') {
$link2 .= '<b>'.$orderpop.'</b> | ';
} else {
$link2 .= '<a href="'.$myurl2.'&amp;sort=popularity'.$courselink.'">'.$orderpop.'</a> | ';
}
if ($sort == 'date') {
$link2 .= '<b>'.$orderdate.'</b>';
} else {
$link2 .= '<a href="'.$myurl2.'&amp;sort=date'.$courselink.'">'.$orderdate.'</a>';
}
// Prepare output
$fclass = '';
// make the tags larger when there are not so many
if (strlen($tags) < 10000) {
$fclass = 'coursetag_more_large';
}
$outstr = '
<div class="coursetag_more_title">
<div style="padding-bottom:5px">'.$welcome.'</div>
<div class="coursetag_more_link">'.$link1.'</div>
<div class="coursetag_more_link">'.$link2.'</div>
</div>
<div class="coursetag_more_tags '.$fclass.'">'.
$tags.'
</div>';
echo $outstr;
echo $OUTPUT->footer();
-330
View File
@@ -1,330 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* coursetagslib.php
*
* @package core_tag
* @copyright 2007 [email protected]
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once $CFG->dirroot.'/tag/lib.php';
require_once $CFG->dirroot.'/tag/locallib.php';
/**
* Returns an ordered array of tags associated with visible courses
* (boosted replacement of get_all_tags() allowing association with user and tagtype).
*
* @package core_tag
* @category tag
* @param int $courseid A course id. Passing 0 will return all distinct tags for all visible courses
* @param int $userid (optional) the user id, a default of 0 will return all users tags for the course
* @param string $tagtype (optional) The type of tag, empty string returns all types. Currently (Moodle 2.2) there are two
* types of tags which are used within Moodle, they are 'official' and 'default'.
* @param int $numtags (optional) number of tags to display, default of 80 is set in the block, 0 returns all
* @param string $unused (optional) was selected sorting, moved to tag_print_cloud()
* @return array
*/
function coursetag_get_tags($courseid, $userid=0, $tagtype='', $numtags=0, $unused = '') {
global $CFG, $DB;
// get visible course ids
$courselist = array();
if ($courseid === 0) {
if ($courses = $DB->get_records_select('course', 'visible=1 AND category>0', null, '', 'id')) {
foreach ($courses as $key => $value) {
$courselist[] = $key;
}
}
}
// get tags from the db ordered by highest count first
$params = array();
$sql = "SELECT id as tkey, name, id, tagtype, rawname, f.timemodified, flag, count
FROM {tag} t,
(SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count
FROM {tag_instance}
WHERE itemtype = 'course' ";
if ($courseid > 0) {
$sql .= " AND itemid = :courseid ";
$params['courseid'] = $courseid;
} else {
if (!empty($courselist)) {
list($usql, $uparams) = $DB->get_in_or_equal($courselist, SQL_PARAMS_NAMED);
$sql .= "AND itemid $usql ";
$params = $params + $uparams;
}
}
if ($userid > 0) {
$sql .= " AND tiuserid = :userid ";
$params['userid'] = $userid;
}
$sql .= " GROUP BY tagid) f
WHERE t.id = f.tagid ";
if ($tagtype != '') {
$sql .= "AND tagtype = :tagtype ";
$params['tagtype'] = $tagtype;
}
$sql .= "ORDER BY count DESC, name ASC";
// limit the number of tags for output
if ($numtags == 0) {
$tags = $DB->get_records_sql($sql, $params);
} else {
$tags = $DB->get_records_sql($sql, $params, 0, $numtags);
}
// prepare the return
$return = array();
if ($tags) {
// avoid print_tag_cloud()'s ksort upsetting ordering by setting the key here
foreach ($tags as $value) {
$return[] = $value;
}
}
return $return;
}
/**
* Returns an ordered array of tags
* (replaces popular_tags_count() allowing sorting).
*
* @package core_tag
* @category tag
* @param string $unused (optional) was selected sorting - moved to tag_print_cloud()
* @param int $numtags (optional) number of tags to display, default of 20 is set in the block, 0 returns all
* @return array
*/
function coursetag_get_all_tags($unused='', $numtags=0) {
global $CFG, $DB;
// note that this selects all tags except for courses that are not visible
$sql = "SELECT id, name, tagtype, rawname, f.timemodified, flag, count
FROM {tag} t,
(SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count
FROM {tag_instance} WHERE tagid NOT IN
(SELECT tagid FROM {tag_instance} ti, {course} c
WHERE c.visible = 0
AND ti.itemtype = 'course'
AND ti.itemid = c.id)
GROUP BY tagid) f
WHERE t.id = f.tagid
ORDER BY count DESC, name ASC";
if ($numtags == 0) {
$tags = $DB->get_records_sql($sql);
} else {
$tags = $DB->get_records_sql($sql, null, 0, $numtags);
}
$return = array();
if ($tags) {
foreach ($tags as $value) {
$return[] = $value;
}
}
return $return;
}
/**
* Returns javascript for use in tags block and supporting pages
*
* @package core_tag
* @category tag
* @return null
*/
function coursetag_get_jscript() {
global $CFG, $DB, $PAGE;
$PAGE->requires->js('/tag/tag.js');
$PAGE->requires->strings_for_js(array('jserror1', 'jserror2'), 'block_tags');
if ($coursetags = $DB->get_records('tag', null, 'name ASC', 'name, id')) {
foreach ($coursetags as $key => $value) {
$PAGE->requires->js_function_call('set_course_tag', array($key));
}
}
$PAGE->requires->js('/blocks/tags/coursetags.js');
return '';
}
/**
* Returns javascript to create the links in the tag block footer.
*
* @package core_tag
* @category tag
* @param string $elementid the element to attach the footer to
* @param array $coursetagslinks links arrays each consisting of 'title', 'onclick' and 'text' elements
* @return string always returns a blank string
*/
function coursetag_get_jscript_links($elementid, $coursetagslinks) {
global $PAGE;
if (!empty($coursetagslinks)) {
foreach ($coursetagslinks as $a) {
$PAGE->requires->js_function_call('add_tag_footer_link', array($elementid, $a['title'], $a['onclick'], $a['text']), true);
}
}
return '';
}
/**
* Returns all tags created by a user for a course
*
* @package core_tag
* @category tag
* @param int $courseid tags are returned for the course that has this courseid
* @param int $userid return tags which were created by this user
*/
function coursetag_get_records($courseid, $userid) {
global $CFG, $DB;
$sql = "SELECT t.id, name, rawname
FROM {tag} t, {tag_instance} ti
WHERE t.id = ti.tagid
AND ti.tiuserid = :userid
AND ti.itemid = :courseid
ORDER BY name ASC";
return $DB->get_records_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid));
}
/**
* Stores a tag for a course for a user
*
* @package core_tag
* @category tag
* @param array $tags simple array of keywords to be stored
* @param int $courseid the id of the course we wish to store a tag for
* @param int $userid the id of the user we wish to store a tag for
* @param string $tagtype official or default only
* @param string $myurl (optional) for logging creation of course tags
*/
function coursetag_store_keywords($tags, $courseid, $userid=0, $tagtype='official', $myurl='') {
global $CFG;
if (is_array($tags) and !empty($tags)) {
foreach ($tags as $tag) {
$tag = trim($tag);
if (strlen($tag) > 0) {
//tag_set_add('course', $courseid, $tag, $userid); //deletes official tags
//add tag if does not exist
if (!$tagid = tag_get_id($tag)) {
$tag_id_array = tag_add(array($tag), $tagtype);
$tagid = $tag_id_array[core_text::strtolower($tag)];
}
//ordering
$ordering = 0;
if ($current_ids = tag_get_tags_ids('course', $courseid)) {
end($current_ids);
$ordering = key($current_ids) + 1;
}
//set type
tag_type_set($tagid, $tagtype);
//tag_instance entry
tag_assign('course', $courseid, $tagid, $ordering, $userid, 'core', context_course::instance($courseid)->id);
}
}
}
}
/**
* Deletes a personal tag for a user for a course.
*
* @package core_tag
* @category tag
* @param int $tagid the tag we wish to delete
* @param int $userid the user that the tag is associated with
* @param int $courseid the course that the tag is associated with
*/
function coursetag_delete_keyword($tagid, $userid, $courseid) {
tag_delete_instance('course', $courseid, $tagid, $userid);
}
/**
* Get courses tagged with a tag
*
* @global moodle_database $DB
* @package core_tag
* @category tag
* @param int $tagid
* @return array of course objects
*/
function coursetag_get_tagged_courses($tagid) {
global $DB;
$courses = array();
$ctxselect = context_helper::get_preload_record_columns_sql('ctx');
$sql = "SELECT c.*, $ctxselect
FROM {course} c
JOIN {tag_instance} t ON t.itemid = c.id
JOIN {context} ctx ON ctx.instanceid = c.id
WHERE t.tagid = :tagid AND
t.itemtype = 'course' AND
ctx.contextlevel = :contextlevel
ORDER BY c.sortorder ASC";
$params = array('tagid' => $tagid, 'contextlevel' => CONTEXT_COURSE);
$rs = $DB->get_recordset_sql($sql, $params);
foreach ($rs as $course) {
context_helper::preload_from_record($course);
if ($course->visible == 1 || has_capability('moodle/course:viewhiddencourses', context_course::instance($course->id))) {
$courses[$course->id] = $course;
}
}
return $courses;
}
/**
* Course tagging function used only during the deletion of a course (called by lib/moodlelib.php) to clean up associated tags
*
* @package core_tag
* @param int $courseid the course we wish to delete tag instances from
* @param bool $showfeedback if we should output a notification of the delete to the end user
*/
function coursetag_delete_course_tags($courseid, $showfeedback=false) {
global $DB, $OUTPUT;
if ($taginstances = $DB->get_recordset_select('tag_instance', "itemtype = 'course' AND itemid = :courseid",
array('courseid' => $courseid), '', 'tagid, tiuserid')) {
foreach ($taginstances as $record) {
tag_delete_instance('course', $courseid, $record->tagid, $record->tiuserid);
}
$taginstances->close();
}
if ($showfeedback) {
echo $OUTPUT->notification(get_string('deletedcoursetags', 'tag'), 'notifysuccess');
}
}
-1
View File
@@ -95,7 +95,6 @@ echo $OUTPUT->heading($tagname, 2);
tag_print_management_box($tag);
tag_print_description_box($tag);
// Check what type of results are avaialable
require_once($CFG->dirroot.'/tag/coursetagslib.php');
$courses = $courserenderer->tagged_courses($tag->id);
if (!empty($CFG->enableblogs) && has_capability('moodle/blog:view', $systemcontext)) {
-42
View File
@@ -28,45 +28,3 @@ YUI().use('yui2-autocomplete', 'yui2-datasource', 'yui2-animation', 'yui2-connec
};
});
}
function ctags_checkinput(val) {
var len = val.length;
if (len < 2 || len > 50) {
alert(M.util.get_string('jserror1', 'block_tags'));
return false;
} else if (val.indexOf("<") > 0) {
alert(M.util.get_string('jserror2', 'block_tags'));
return false;
} else if (val.indexOf(">") > 0) {
alert(M.util.get_string('jserror2', 'block_tags'));
return false;
} else {
return true;
}
}
function set_course_tag(key) {
window.coursetag_tags[window.coursetag_tags.length] = key;
}
function add_tag_footer_link(eid, ltitle, laction, ltext) {
var e = document.getElementById(eid);
if (e) {
var link = document.createElement('a');
link.setAttribute('href', '');
link.setAttribute('title', ltitle);
link.appendChild(document.createTextNode(ltext));
var callback = function () {
ctags_show_div(laction);
};
YUI().use('yui2-event', function(Y) {
Y.YUI2.util.Event.addListener(link, 'click', callback);
});
if (e.childNodes.length > 0) {
e.appendChild(document.createTextNode(' | '));
} else {
e.appendChild(document.createElement('hr'));
}
e.appendChild(link);
}
}
+4 -1
View File
@@ -28,7 +28,6 @@ defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/tag/lib.php');
require_once($CFG->dirroot . '/tag/coursetagslib.php');
// Used to create a wiki page to tag.
require_once($CFG->dirroot . '/mod/wiki/locallib.php');
@@ -166,6 +165,7 @@ class core_tag_events_testcase extends advanced_testcase {
// Trigger and capture the event for untagging a course.
$sink = $this->redirectEvents();
coursetag_delete_keyword($tag->id, 2, $course->id);
$this->assertDebuggingCalled();
$events = $sink->get_events();
$event = reset($events);
@@ -415,6 +415,7 @@ class core_tag_events_testcase extends advanced_testcase {
// Trigger and capture the event for deleting a personal tag for a user for a course.
$sink = $this->redirectEvents();
coursetag_delete_keyword($tag->id, 2, $course->id);
$this->assertDebuggingCalled();
$events = $sink->get_events();
$event = $events[1];
@@ -432,6 +433,7 @@ class core_tag_events_testcase extends advanced_testcase {
// Trigger and capture the event for deleting all tags in a course.
$sink = $this->redirectEvents();
coursetag_delete_course_tags($course->id);
$this->assertDebuggingCalled();
$events = $sink->get_events();
$event = $events[1];
@@ -451,6 +453,7 @@ class core_tag_events_testcase extends advanced_testcase {
// Trigger and capture the event for deleting all tags in a course.
$sink = $this->redirectEvents();
coursetag_delete_course_tags($course->id);
$this->assertDebuggingCalled();
$events = $sink->get_events();
$events = array($events[1], $events[3]);
+7
View File
@@ -1,6 +1,13 @@
This files describes API changes in tagging, information provided
here is intended especially for developers.
=== 3.0 ===
* Tagging courses is now implemented without user id - through course edit form or
special "Course tags" form. All coursetag_* functions in /tag/coursetagslib.php
were deprecated without replacement and related JS code was removed. Config variable
$CFG->block_tags_showcoursetags was removed.
=== 2.7 ===
* The functions tag_set, tag_set_add, tag_set_delete and tag_assign now expect the component
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2015090800.00; // YYYYMMDD = weekly release date of this DEV branch.
$version = 2015090801.00; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.