$string['cachedef_plugin_manager'] = 'Plugin info manager';
$string['cachedef_questiondata'] = 'Question definitions';
$string['cachedef_repositories'] = 'Repositories instances data';
-$string['cachedef_search_results'] = 'Search results user data';
$string['cachedef_grade_categories'] = 'Grade category queries';
$string['cachedef_string'] = 'Language string cache';
$string['cachedef_tags'] = 'Tags collections and areas';
'staticacceleration' => true,
),
- // Caches search results.
- 'search_results' => array(
- 'mode' => cache_store::MODE_SESSION,
- 'simplekeys' => true,
- 'staticacceleration' => true,
- 'staticaccelerationsize' => 3
- ),
-
// Grade categories. Stored at session level as invalidation is very aggressive.
'grade_categories' => array(
'mode' => cache_store::MODE_SESSION,
'eventname' => '\core\event\user_updated',
'callback' => 'core_badges_observer::profile_criteria_review',
),
- array(
- 'eventname' => '\core\event\search_indexed',
- 'callback' => 'core_search_observer::invalidate_caches',
- ),
);
// List of all events triggered by Moodle can be found using Events list report.
}
if (!empty($pagingbar->lastlink)) {
- $output .= ' ...' . $pagingbar->lastlink . ' ';
+ $output .= ' ... ' . $pagingbar->lastlink . ' ';
}
if (!empty($pagingbar->nextlink)) {
'rid' => $recordid,
));
redirect($viewurl);
+ } else if (!empty($datarecord->saveandadd)) {
+ // User has clicked "Save and add another". Reset all of the fields.
+ $datarecord = null;
}
}
}
echo ' <input type="submit" name="cancel" value="'.get_string('cancel').'" onclick="javascript:history.go(-1)" />';
} else {
if ((!$data->maxentries) || has_capability('mod/data:manageentries', $context) || (data_numentries($data) < ($data->maxentries - 1))) {
- echo ' <input type="submit" value="'.get_string('saveandadd','data').'" />';
+ echo ' <input type="submit" name="saveandadd" value="' . get_string('saveandadd', 'data') . '" />';
}
}
echo '</div>';
And I add an entry to "Test database name" database with:
| Test field name | Student second entry |
And I press "Save and add another"
+ And the field "Test field name" does not match value "Student second entry"
And I add an entry to "Test database name" database with:
| Test field name | Student third entry |
And I press "Save and view"
* @return string
*/
public function format_message_text($cm, $post) {
+ $message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php',
+ \context_module::instance($cm->id)->id,
+ 'mod_forum', 'post', $post->id);
$options = new \stdClass();
$options->para = true;
- return format_text($post->message, $post->messageformat, $options);
+ return format_text($message, $post->messageformat, $options);
}
/**
$string['configdigestmailtime'] = 'People who choose to have emails sent to them in digest form will be emailed the digest daily. This setting controls which time of day the daily mail will be sent (the next cron that runs after this hour will send it).';
$string['configdisplaymode'] = 'The default display mode for discussions if one isn\'t set.';
$string['configenablerssfeeds'] = 'This switch will enable the possibility of RSS feeds for all forums. You will still need to turn feeds on manually in the settings for each forum.';
-$string['configenabletimedposts'] = 'Set to \'yes\' if you want to allow setting of display periods when posting a new forum discussion (Experimental as not yet fully tested)';
+$string['configenabletimedposts'] = 'Set to \'yes\' if you want to allow setting of display periods when posting a new forum discussion.';
$string['configlongpost'] = 'Any post over this length (in characters not including HTML) is considered long. Posts displayed on the site front page, social format course pages, or user profiles are shortened to a natural break somewhere between the forum_shortpost and forum_longpost values.';
$string['configmanydiscussions'] = 'Maximum number of discussions shown in a forum per page';
$string['configmaxattachments'] = 'Default maximum number of attachments allowed per post.';
}
$settings->add(new admin_setting_configcheckbox('forum_enabletimedposts', get_string('timedposts', 'forum'),
- get_string('configenabletimedposts', 'forum'), 0));
+ get_string('configenabletimedposts', 'forum'), 1));
}
'Hello Moodle&', 'Welcome to Moodle&');
$textcases['Text mail with ampersands everywhere'] = array('data' => $newcase);
+ // Text+image message i.e. @@PLUGINFILE@@ token handling.
+ $newcase = $base;
+ $newcase['forums'][0]['forumposts'][0]['name'] = 'Text and image';
+ $newcase['forums'][0]['forumposts'][0]['message'] = 'Welcome to Moodle, '
+ .'@@PLUGINFILE@@/Screen%20Shot%202016-03-22%20at%205.54.36%20AM%20%281%29.png !';
+ $newcase['expectations'][0]['subject'] = '.*101.*Text and image';
+ $newcase['expectations'][0]['contents'] = array(
+ '~{$a',
+ '~&(amp|lt|gt|quot|\#039);(?!course)',
+ 'Attachment example.txt:\n' .
+ 'http://www.example.com/moodle/pluginfile.php/\d*/mod_forum/attachment/\d*/example.txt\n',
+ 'Text and image', 'Moodle Forum',
+ 'Welcome to Moodle, *\n.*'
+ .'http://www.example.com/moodle/pluginfile.php/\d+/mod_forum/post/\d+/'
+ .'Screen%20Shot%202016-03-22%20at%205\.54\.36%20AM%20%281%29\.png *\n.*!',
+ 'Love Moodle', '1\d1');
+ $textcases['Text mail with text+image message i.e. @@PLUGINFILE@@ token handling'] = array('data' => $newcase);
+
// Now the html cases.
$htmlcases = array();
'>Welcome.*Moodle\'">&', '>Love Moodle&\#039;">&', '>101\'">&');
$htmlcases['HTML mail with quotes, gt, lt and ampersand everywhere'] = array('data' => $newcase);
+ // Text+image message i.e. @@PLUGINFILE@@ token handling.
+ $newcase = $htmlbase;
+ $newcase['forums'][0]['forumposts'][0]['name'] = 'HTML text and image';
+ $newcase['forums'][0]['forumposts'][0]['message'] = '<p>Welcome to Moodle, '
+ .'<img src="@@PLUGINFILE@@/Screen%20Shot%202016-03-22%20at%205.54.36%20AM%20%281%29.png"'
+ .' alt="" width="200" height="393" class="img-responsive" />!</p>';
+ $newcase['expectations'][0]['subject'] = '.*101.*HTML text and image';
+ $newcase['expectations'][0]['contents'] = array(
+ '~{\$a',
+ '~&(amp|lt|gt|quot|\#039);(?!course)',
+ '<div class="attachments">( *\n *)?<a href',
+ '<div class="subject">\n.*HTML text and image', '>Moodle Forum',
+ '<p>Welcome to Moodle, '
+ .'<img src="http://www.example.com/moodle/pluginfile.php/\d+/mod_forum/post/\d+/'
+ .'Screen%20Shot%202016-03-22%20at%205\.54\.36%20AM%20%281%29\.png"'
+ .' alt="" width="200" height="393" class="img-responsive" />!</p>',
+ '>Love Moodle', '>1\d1');
+ $htmlcases['HTML mail with text+image message i.e. @@PLUGINFILE@@ token handling'] = array('data' => $newcase);
+
return $textcases + $htmlcases;
}
$type->secureicon = $config->lti_secureicon;
}
- if (isset($config->lti_forcessl)) {
- $type->forcessl = !empty($config->lti_forcessl) ? $config->lti_forcessl : 0;
- $config->lti_forcessl = $type->forcessl;
- }
+ $type->forcessl = !empty($config->lti_forcessl) ? $config->lti_forcessl : 0;
+ $config->lti_forcessl = $type->forcessl;
$type->timemodified = time();
$this->assertEquals($ncount, $rncount, 'All newline characters should be a combination of \r\n');
}
+
+ /**
+ * Tests lti_prepare_type_for_save's handling of the "Force SSL" configuration.
+ */
+ public function test_lti_prepare_type_for_save_forcessl() {
+ $type = new stdClass();
+ $config = new stdClass();
+
+ // Try when the forcessl config property is not set.
+ lti_prepare_type_for_save($type, $config);
+ $this->assertObjectHasAttribute('lti_forcessl', $config);
+ $this->assertEquals(0, $config->lti_forcessl);
+ $this->assertEquals(0, $type->forcessl);
+
+ // Try when forcessl config property is set.
+ $config->lti_forcessl = 1;
+ lti_prepare_type_for_save($type, $config);
+ $this->assertObjectHasAttribute('lti_forcessl', $config);
+ $this->assertEquals(1, $config->lti_forcessl);
+ $this->assertEquals(1, $type->forcessl);
+
+ // Try when forcessl config property is set to 0.
+ $config->lti_forcessl = 0;
+ lti_prepare_type_for_save($type, $config);
+ $this->assertObjectHasAttribute('lti_forcessl', $config);
+ $this->assertEquals(0, $config->lti_forcessl);
+ $this->assertEquals(0, $type->forcessl);
+ }
}
if (!empty($data->all) || $anydelete) {
echo $OUTPUT->notification(get_string('deleted', 'report_search'), 'notifysuccess');
-
- // Purge the cache.
- $cache = \cache::make('core', 'search_results');
- $cache->purge();
}
}
public function check_access($id) {
global $DB;
- $activity = $this->get_activity($id);
try {
+ $activity = $this->get_activity($id);
$cminfo = $this->get_cm($this->get_module_name(), $activity->id, $activity->course);
$cminfo->get_course_module_record();
} catch (\dml_missing_record_exception $ex) {
public function search(\stdClass $formdata) {
global $USER;
- $cache = \cache::make('core', 'search_results');
-
- // Generate a string from all query filters
- // Not including $areascontext here, being a user cache it is not needed.
- $querykey = $this->generate_query_key($formdata, $USER->id);
-
- // Look for cached results before executing it.
- if ($results = $cache->get($querykey)) {
- return $results;
- }
-
// Clears previous query errors.
$this->engine->clear_query_error();
$docs = $this->engine->execute_query($formdata, $areascontexts);
}
- // Cache results.
- $cache->set($querykey, $docs);
-
return $docs;
}
- /**
- * We generate the key ourselves so MUC knows that it contains simplekeys.
- *
- * @param stdClass $formdata
- * @return string
- */
- protected function generate_query_key($formdata) {
- global $USER;
-
- // Empty values by default (although q should always have a value).
- $fields = array('q', 'title', 'areaid', 'timestart', 'timeend', 'page');
-
- // Just in this function scope.
- $params = clone $formdata;
- foreach ($fields as $field) {
- if (empty($params->{$field})) {
- $params->{$field} = '';
- }
- }
-
- // Although it is not likely, we prevent cache hits if available search areas change during the session.
- $enabledareas = implode('-', array_keys(static::get_search_areas_list(true)));
-
- return md5($params->q . 'userid=' . $USER->id . 'title=' . $params->title . 'areaid=' . $params->areaid .
- 'timestart=' . $params->timestart . 'timeend=' . $params->timeend . 'page=' . $params->page .
- $enabledareas);
- }
-
/**
* Merge separate index segments into one.
*/
+++ /dev/null
-<?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/>.
-
-/**
- * Events observer for core_search purposes.
- *
- * @package core_search
- * @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Event observer for search.
- *
- * @package core_search
- * @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class core_search_observer {
-
- /**
- * Invalidates search results cache.
- *
- * Quite aggressive as search_results cache is per session.
- *
- * @param \core\event\search_indexed $event
- * @return void
- */
- public static function invalidate_caches(\core\event\search_indexed $event) {
- $cache = \cache::make('core', 'search_results');
- $cache->purge();
- }
-}
} else {
$settings->add(new admin_setting_heading('search_solr_connection',
new lang_string('connectionsettings', 'search_solr'), ''));
- $settings->add(new admin_setting_configtext('search_solr/server_hostname', new lang_string('solrserverhostname', 'search_solr'), new lang_string('solrserverhostname_desc', 'search_solr'), '127.0.0.1', PARAM_TEXT));
- $settings->add(new admin_setting_configtext('search_solr/indexname', new lang_string('solrindexname', 'search_solr'), '', 'moodle', PARAM_TEXT));
+ $settings->add(new admin_setting_configtext('search_solr/server_hostname', new lang_string('solrserverhostname', 'search_solr'), new lang_string('solrserverhostname_desc', 'search_solr'), '127.0.0.1', PARAM_HOST));
+ $settings->add(new admin_setting_configtext('search_solr/indexname', new lang_string('solrindexname', 'search_solr'), '', '', PARAM_ALPHANUMEXT));
$settings->add(new admin_setting_configcheckbox('search_solr/secure', new lang_string('solrsecuremode', 'search_solr'), '', 0, 1, 0));
$secure = get_config('search_solr', 'secure');
$this->assertEquals($USER->id, $results[0]->get('userid'));
$this->assertEquals(\context_system::instance()->id, $results[0]->get('contextid'));
- // Testing filters we don't purge cache in between assertions because cache key depends on the whole filters set
- // and they are different.
sleep(1);
$beforeadding = time();
sleep(1);
unset($querydata->timeend);
$querydata->title = 'moodle/course:renameroles roleid 1';
$this->assertCount(1, $this->search->search($querydata));
+
+ // Check that index contents get updated.
+ $DB->delete_records('role_capabilities', array('capability' => 'moodle/course:renameroles'));
+ $this->search->index(true);
+ unset($querydata->title);
+ $querydata->q = '*renameroles*';
+ $this->assertCount(0, $this->search->search($querydata));
}
public function test_delete() {
$areaid = \core_search\manager::generate_areaid('core_mocksearch', 'role_capabilities');
$this->search->delete_index($areaid);
- cache_helper::purge_by_definition('core', 'search_results');
$this->assertCount(0, $this->search->search($querydata));
}
// Reindex the document with the changed files.
$engine->add_document($doc, true);
$engine->area_index_complete($area->get_area_id());
- cache_helper::purge_by_definition('core', 'search_results');
// Go through our check array, and see if the file is there or not.
foreach ($checkfiles as $key => $keep) {
$deleteid = $first->get('id');
$engine->delete_by_id($deleteid);
- cache_helper::purge_by_definition('core', 'search_results');
// Check that we don't get a result for it anymore.
$results = $this->search->search($querydata);
}
public function check_access($id) {
- return \core_search\manager::ACCESS_GRANTED;
+ global $DB;
+
+ if ($DB->get_record('role_capabilities', array('id' => $id))) {
+ return \core_search\manager::ACCESS_GRANTED;
+ }
+ return \core_search\manager::ACCESS_DELETED;
}
public function get_doc_url(\core_search\document $doc) {
defined('MOODLE_INTERNAL') || die();
-$version = 2016033100.00; // YYYYMMDD = weekly release date of this DEV branch.
+$version = 2016033100.01; // YYYYMMDD = weekly release date of this DEV branch.
// RR = release increments - 00 in DEV branches.
// .XX = incremental changes.