Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
integration
prechecker
Commits
97812f14
Commit
97812f14
authored
Dec 06, 2017
by
Damyon Wiese
Committed by
jun
Dec 06, 2017
Browse files
Merge branch 'MDL-60880-master' of
https://github.com/sammarshallou/moodle
parents
e3b699ea
7f9fb2c8
Changes
14
Hide whitespace changes
Inline
Side-by-side
blocks/globalsearch/block_globalsearch.php
View file @
97812f14
...
...
@@ -78,6 +78,12 @@ class block_globalsearch extends block_base {
'type'
=>
'text'
,
'size'
=>
'15'
);
$this
->
content
->
text
.
=
html_writer
::
empty_tag
(
'input'
,
$inputoptions
);
// Context id.
if
(
$this
->
page
->
context
&&
$this
->
page
->
context
->
contextlevel
!==
CONTEXT_SYSTEM
)
{
$this
->
content
->
text
.
=
html_writer
::
empty_tag
(
'input'
,
[
'type'
=>
'hidden'
,
'name'
=>
'context'
,
'value'
=>
$this
->
page
->
context
->
id
]);
}
// Search button.
$this
->
content
->
text
.
=
html_writer
::
tag
(
'button'
,
get_string
(
'search'
,
'search'
),
array
(
'id'
=>
'searchform_button'
,
'type'
=>
'submit'
,
'title'
=>
'globalsearch'
,
'class'
=>
'btn btn-secondary'
));
...
...
lang/en/search.php
View file @
97812f14
...
...
@@ -53,6 +53,7 @@ $string['engineserverstatus'] = 'The search engine is not available. Please cont
$string
[
'enteryoursearchquery'
]
=
'Enter your search query'
;
$string
[
'errors'
]
=
'Errors'
;
$string
[
'errorareanotavailable'
]
=
'{$a} search area is not available.'
;
$string
[
'everywhere'
]
=
'Everywhere you can access'
;
$string
[
'filesinindexdirectory'
]
=
'Files in index directory'
;
$string
[
'filterheader'
]
=
'Filter'
;
$string
[
'fromtime'
]
=
'Modified after'
;
...
...
@@ -89,6 +90,7 @@ $string['searcharea'] = 'Search area';
$string
[
'searching'
]
=
'Searching in ...'
;
$string
[
'searchnotpermitted'
]
=
'You are not allowed to do a search'
;
$string
[
'searchsetupdescription'
]
=
'The following steps help you to set up Moodle global search.'
;
$string
[
'searchwithin'
]
=
'Search within'
;
$string
[
'seconds'
]
=
'seconds'
;
$string
[
'solutions'
]
=
'Solutions'
;
$string
[
'statistics'
]
=
'Statistics'
;
...
...
lib/outputrenderers.php
View file @
97812f14
...
...
@@ -3259,6 +3259,10 @@ EOD;
$contents
=
html_writer
::
tag
(
'label'
,
get_string
(
'enteryoursearchquery'
,
'search'
),
array
(
'for'
=>
'id_q_'
.
$id
,
'class'
=>
'accesshide'
))
.
html_writer
::
tag
(
'input'
,
''
,
$inputattrs
);
if
(
$this
->
page
->
context
&&
$this
->
page
->
context
->
contextlevel
!==
CONTEXT_SYSTEM
)
{
$contents
.
=
html_writer
::
empty_tag
(
'input'
,
[
'type'
=>
'hidden'
,
'name'
=>
'context'
,
'value'
=>
$this
->
page
->
context
->
id
]);
}
$searchinput
=
html_writer
::
tag
(
'form'
,
$contents
,
$formattrs
);
return
html_writer
::
tag
(
'div'
,
$searchicon
.
$searchinput
,
array
(
'class'
=>
'search-input-wrapper nav-link'
,
'id'
=>
$id
));
...
...
search/classes/manager.php
View file @
97812f14
...
...
@@ -360,14 +360,22 @@ class manager {
* information and there will be a performance benefit on passing only some contexts
* instead of the whole context array set.
*
* The areas can be limited by course id and context id. If specifying context ids, results
* are limited to the exact context ids specified and not their children (for example, giving
* the course context id would result in including search items with the course context id, and
* not anything from a context inside the course). For performance, you should also specify
* course id(s) when using context ids.
*
* @param array|false $limitcourseids An array of course ids to limit the search to. False for no limiting.
* @param array|false $limitcontextids An array of context ids to limit the search to. False for no limiting.
* @return bool|array Indexed by area identifier (component + area name). Returns true if the user can see everything.
*/
protected
function
get_areas_user_accesses
(
$limitcourseids
=
false
)
{
protected
function
get_areas_user_accesses
(
$limitcourseids
=
false
,
$limitcontextids
=
false
)
{
global
$DB
,
$USER
;
// All results for admins. Eventually we could add a new capability for managers.
if
(
is_siteadmin
())
{
// All results for admins (unless they have chosen to limit results). Eventually we could
// add a new capability for managers.
if
(
is_siteadmin
()
&&
!
$limitcourseids
&&
!
$limitcontextids
)
{
return
true
;
}
...
...
@@ -392,23 +400,42 @@ class manager {
// want to allow guests to retrieve data from them.
$systemcontextid
=
\
context_system
::
instance
()
->
id
;
foreach
(
$areasbylevel
[
CONTEXT_SYSTEM
]
as
$areaid
=>
$searchclass
)
{
$areascontexts
[
$areaid
][
$systemcontextid
]
=
$systemcontextid
;
if
(
!
$limitcontextids
||
in_array
(
$systemcontextid
,
$limitcontextids
))
{
foreach
(
$areasbylevel
[
CONTEXT_SYSTEM
]
as
$areaid
=>
$searchclass
)
{
$areascontexts
[
$areaid
][
$systemcontextid
]
=
$systemcontextid
;
}
}
}
if
(
!
empty
(
$areasbylevel
[
CONTEXT_USER
]))
{
if
(
$usercontext
=
\
context_user
::
instance
(
$USER
->
id
,
IGNORE_MISSING
))
{
// Extra checking although only logged users should reach this point, guest users have a valid context id.
foreach
(
$areasbylevel
[
CONTEXT_USER
]
as
$areaid
=>
$searchclass
)
{
$areascontexts
[
$areaid
][
$usercontext
->
id
]
=
$usercontext
->
id
;
if
(
!
$limitcontextids
||
in_array
(
$usercontext
->
id
,
$limitcontextids
))
{
// Extra checking although only logged users should reach this point, guest users have a valid context id.
foreach
(
$areasbylevel
[
CONTEXT_USER
]
as
$areaid
=>
$searchclass
)
{
$areascontexts
[
$areaid
][
$usercontext
->
id
]
=
$usercontext
->
id
;
}
}
}
}
// Get the courses where the current user has access.
$courses
=
enrol_get_my_courses
(
array
(
'id'
,
'cacherev'
),
'id'
,
0
,
[],
(
bool
)
get_config
(
'core'
,
'searchallavailablecourses'
));
if
(
is_siteadmin
())
{
// Admins have access to all courses regardless of enrolment.
if
(
$limitcourseids
)
{
list
(
$coursesql
,
$courseparams
)
=
$DB
->
get_in_or_equal
(
$limitcourseids
);
$coursesql
=
'id '
.
$coursesql
;
}
else
{
$coursesql
=
''
;
$courseparams
=
[];
}
// Get courses using the same list of fields from enrol_get_my_courses.
$courses
=
$DB
->
get_records_select
(
'course'
,
$coursesql
,
$courseparams
,
''
,
'id, category, sortorder, shortname, fullname, idnumber, startdate, visible, '
.
'groupmode, groupmodeforce, cacherev'
);
}
else
{
// Get the courses where the current user has access.
$courses
=
enrol_get_my_courses
(
array
(
'id'
,
'cacherev'
),
'id'
,
0
,
[],
(
bool
)
get_config
(
'core'
,
'searchallavailablecourses'
));
}
if
(
empty
(
$limitcourseids
)
||
in_array
(
SITEID
,
$limitcourseids
))
{
$courses
[
SITEID
]
=
get_course
(
SITEID
);
...
...
@@ -429,7 +456,8 @@ class manager {
// Info about the course modules.
$modinfo
=
get_fast_modinfo
(
$course
);
if
(
!
empty
(
$areasbylevel
[
CONTEXT_COURSE
]))
{
if
(
!
empty
(
$areasbylevel
[
CONTEXT_COURSE
])
&&
(
!
$limitcontextids
||
in_array
(
$coursecontext
->
id
,
$limitcontextids
)))
{
// Add the course contexts the user can view.
foreach
(
$areasbylevel
[
CONTEXT_COURSE
]
as
$areaid
=>
$searchclass
)
{
if
(
$course
->
visible
||
has_capability
(
'moodle/course:viewhiddencourses'
,
$coursecontext
))
{
...
...
@@ -448,6 +476,10 @@ class manager {
$modinstances
=
$modinfo
->
get_instances_of
(
$modulename
);
foreach
(
$modinstances
as
$modinstance
)
{
// Skip module context if not included in list of context ids.
if
(
$limitcontextids
&&
!
in_array
(
$modinstance
->
context
->
id
,
$limitcontextids
))
{
continue
;
}
if
(
$modinstance
->
uservisible
)
{
$areascontexts
[
$areaid
][
$modinstance
->
context
->
id
]
=
$modinstance
->
context
->
id
;
}
...
...
@@ -468,6 +500,14 @@ class manager {
// Get list of course contexts.
list
(
$contextsql
,
$contextparams
)
=
$DB
->
get_in_or_equal
(
$coursecontextids
);
// Get list of block context (if limited).
$blockcontextwhere
=
''
;
$blockcontextparams
=
[];
if
(
$limitcontextids
)
{
list
(
$blockcontextsql
,
$blockcontextparams
)
=
$DB
->
get_in_or_equal
(
$limitcontextids
);
$blockcontextwhere
=
'AND x.id '
.
$blockcontextsql
;
}
// Query all blocks that are within an included course, and are set to be visible, and
// in a supported page type (basically just course view). This query could be
// extended (or a second query added) to support blocks that are within a module
...
...
@@ -482,6 +522,7 @@ class manager {
AND bp.subpage = ''
AND bp.visible = 0
WHERE bi.parentcontextid
$contextsql
$blockcontextwhere
AND bi.blockname
$blocknamesql
AND bi.subpagepattern IS NULL
AND (bi.pagetypepattern = 'site-index'
...
...
@@ -489,7 +530,7 @@ class manager {
OR bi.pagetypepattern = 'course-*'
OR bi.pagetypepattern = '*')
AND bp.id IS NULL"
,
array_merge
([
CONTEXT_BLOCK
],
$contextparams
,
$blocknameparams
));
array_merge
([
CONTEXT_BLOCK
],
$contextparams
,
$blockcontextparams
,
$blocknameparams
));
$blockcontextsbyname
=
[];
foreach
(
$blockrecs
as
$blockrec
)
{
if
(
empty
(
$blockcontextsbyname
[
$blockrec
->
blockname
]))
{
...
...
@@ -579,8 +620,13 @@ class manager {
*
* It might return the results from the cache instead.
*
* @param stdClass $formdata
* @param int $limit The maximum number of documents to return
* Valid formdata options include:
* - q (query text)
* - courseids (optional list of course ids to restrict)
* - contextids (optional list of context ids to restrict)
*
* @param \stdClass $formdata Query input data (usually from search form)
* @param int $limit The maximum number of documents to return
* @return \core_search\document[]
*/
public
function
search
(
\
stdClass
$formdata
,
$limit
=
0
)
{
...
...
@@ -623,10 +669,15 @@ class manager {
$limitcourseids
=
$formdata
->
courseids
;
}
$limitcontextids
=
false
;
if
(
!
empty
(
$formdata
->
contextids
))
{
$limitcontextids
=
$formdata
->
contextids
;
}
// Clears previous query errors.
$this
->
engine
->
clear_query_error
();
$areascontexts
=
$this
->
get_areas_user_accesses
(
$limitcourseids
);
$areascontexts
=
$this
->
get_areas_user_accesses
(
$limitcourseids
,
$limitcontextids
);
if
(
!
$areascontexts
)
{
// User can not access any context.
$docs
=
array
();
...
...
search/classes/output/form/search.php
View file @
97812f14
...
...
@@ -48,6 +48,13 @@ class search extends \moodleform {
$mform
->
setType
(
'q'
,
PARAM_TEXT
);
$mform
->
addRule
(
'q'
,
get_string
(
'required'
),
'required'
,
null
,
'client'
);
// Show the 'search within' option if the user came from a particular context.
if
(
!
empty
(
$this
->
_customdata
[
'searchwithin'
]))
{
$mform
->
addElement
(
'select'
,
'searchwithin'
,
get_string
(
'searchwithin'
,
'search'
),
$this
->
_customdata
[
'searchwithin'
]);
$mform
->
setDefault
(
'searchwithin'
,
''
);
}
$mform
->
addElement
(
'header'
,
'filtersection'
,
get_string
(
'filterheader'
,
'search'
));
$mform
->
setExpanded
(
'filtersection'
,
false
);
...
...
@@ -79,12 +86,21 @@ class search extends \moodleform {
$mform
->
addElement
(
'course'
,
'courseids'
,
get_string
(
'courses'
,
'core'
),
$options
);
$mform
->
setType
(
'courseids'
,
PARAM_INT
);
// Course options should be hidden if we choose to search within a specific location.
if
(
!
empty
(
$this
->
_customdata
[
'searchwithin'
]))
{
$mform
->
hideIf
(
'courseids'
,
'searchwithin'
,
'ne'
,
''
);
}
$mform
->
addElement
(
'date_time_selector'
,
'timestart'
,
get_string
(
'fromtime'
,
'search'
),
array
(
'optional'
=>
true
));
$mform
->
setDefault
(
'timestart'
,
0
);
$mform
->
addElement
(
'date_time_selector'
,
'timeend'
,
get_string
(
'totime'
,
'search'
),
array
(
'optional'
=>
true
));
$mform
->
setDefault
(
'timeend'
,
0
);
// Source context i.e. the page they came from when they clicked search.
$mform
->
addElement
(
'hidden'
,
'context'
);
$mform
->
setType
(
'context'
,
PARAM_INT
);
$this
->
add_action_buttons
(
false
,
get_string
(
'search'
,
'search'
));
}
}
search/engine/solr/classes/engine.php
View file @
97812f14
...
...
@@ -137,6 +137,11 @@ class engine extends \core_search\engine {
// Create the query object.
$query
=
$this
->
create_user_query
(
$filters
,
$usercontexts
);
// If the query cannot have results, return none.
if
(
!
$query
)
{
return
[];
}
// We expect good match rates, so for our first get, we will get a small number of records.
// This significantly speeds solr response time for first few pages.
$query
->
setRows
(
min
(
$limit
*
3
,
static
::
QUERY_SIZE
));
...
...
@@ -242,7 +247,7 @@ class engine extends \core_search\engine {
*
* @param stdClass $filters Containing query and filters.
* @param array $usercontexts Contexts where the user has access. True if the user can access all contexts.
* @return SolrDisMaxQuery
* @return
\
SolrDisMaxQuery
|null Query object or null if they can't get any results
*/
protected
function
create_user_query
(
$filters
,
$usercontexts
)
{
global
$USER
;
...
...
@@ -305,7 +310,7 @@ class engine extends \core_search\engine {
}
if
(
empty
(
$allcontexts
))
{
// This means there are no valid contexts for them, so they get no results.
return
array
()
;
return
null
;
}
$query
->
addFilterQuery
(
'contextid:('
.
implode
(
' OR '
,
$allcontexts
)
.
')'
);
}
...
...
search/engine/solr/tests/engine_test.php
View file @
97812f14
...
...
@@ -209,7 +209,7 @@ class search_solr_engine_testcase extends advanced_testcase {
// Based on core_mocksearch\search\indexer.
$this
->
assertEquals
(
$USER
->
id
,
$results
[
0
]
->
get
(
'userid'
));
$this
->
assertEquals
(
\
context_
system
::
instance
()
->
id
,
$results
[
0
]
->
get
(
'contextid'
));
$this
->
assertEquals
(
\
context_
course
::
instance
(
SITEID
)
->
id
,
$results
[
0
]
->
get
(
'contextid'
));
// Do a test to make sure we aren't searching non-query fields, like areaid.
$querydata
->
q
=
\
core_search\manager
::
generate_areaid
(
'core_mocksearch'
,
'mock_search_area'
);
...
...
@@ -758,4 +758,91 @@ class search_solr_engine_testcase extends advanced_testcase {
$this
->
assertCount
(
10
,
$results
->
results
);
$this
->
assertEquals
(
1
,
$results
->
actualpage
);
}
/**
* Tests searching for results restricted to context id.
*/
public
function
test_context_restriction
()
{
// Use real search areas.
$this
->
search
->
clear_static
();
$this
->
search
->
add_core_search_areas
();
// Create 2 courses and some forums.
$generator
=
$this
->
getDataGenerator
();
$course1
=
$generator
->
create_course
([
'fullname'
=>
'Course 1'
,
'summary'
=>
'xyzzy'
]);
$contextc1
=
\
context_course
::
instance
(
$course1
->
id
);
$course1forum1
=
$generator
->
create_module
(
'forum'
,
[
'course'
=>
$course1
,
'name'
=>
'C1F1'
,
'intro'
=>
'xyzzy'
]);
$contextc1f1
=
\
context_module
::
instance
(
$course1forum1
->
cmid
);
$course1forum2
=
$generator
->
create_module
(
'forum'
,
[
'course'
=>
$course1
,
'name'
=>
'C1F2'
,
'intro'
=>
'xyzzy'
]);
$contextc1f2
=
\
context_module
::
instance
(
$course1forum2
->
cmid
);
$course2
=
$generator
->
create_course
([
'fullname'
=>
'Course 2'
,
'summary'
=>
'xyzzy'
]);
$contextc2
=
\
context_course
::
instance
(
$course1
->
id
);
$course2forum
=
$generator
->
create_module
(
'forum'
,
[
'course'
=>
$course2
,
'name'
=>
'C2F'
,
'intro'
=>
'xyzzy'
]);
$contextc2f
=
\
context_module
::
instance
(
$course2forum
->
cmid
);
// Index the courses and forums.
$this
->
search
->
index
();
// Search as admin user should find everything.
$querydata
=
new
stdClass
();
$querydata
->
q
=
'xyzzy'
;
$results
=
$this
->
search
->
search
(
$querydata
);
$this
->
assert_result_titles
(
[
'Course 1'
,
'Course 2'
,
'C1F1'
,
'C1F2'
,
'C2F'
],
$results
);
// Admin user manually restricts results by context id to include one course and one forum.
$querydata
->
contextids
=
[
$contextc2f
->
id
,
$contextc1
->
id
];
$results
=
$this
->
search
->
search
(
$querydata
);
$this
->
assert_result_titles
([
'Course 1'
,
'C2F'
],
$results
);
// Student enrolled in only one course, same restriction, only has the available results.
$student2
=
$generator
->
create_user
();
$generator
->
enrol_user
(
$student2
->
id
,
$course2
->
id
,
'student'
);
$this
->
setUser
(
$student2
);
$results
=
$this
->
search
->
search
(
$querydata
);
$this
->
assert_result_titles
([
'C2F'
],
$results
);
// Student enrolled in both courses, same restriction, same results as admin.
$student1
=
$generator
->
create_user
();
$generator
->
enrol_user
(
$student1
->
id
,
$course1
->
id
,
'student'
);
$generator
->
enrol_user
(
$student1
->
id
,
$course2
->
id
,
'student'
);
$this
->
setUser
(
$student1
);
$results
=
$this
->
search
->
search
(
$querydata
);
$this
->
assert_result_titles
([
'Course 1'
,
'C2F'
],
$results
);
// Restrict both course and context.
$querydata
->
courseids
=
[
$course2
->
id
];
$results
=
$this
->
search
->
search
(
$querydata
);
$this
->
assert_result_titles
([
'C2F'
],
$results
);
unset
(
$querydata
->
courseids
);
// Restrict both area and context.
$querydata
->
areaids
=
[
'core_course-mycourse'
];
$results
=
$this
->
search
->
search
(
$querydata
);
$this
->
assert_result_titles
([
'Course 1'
],
$results
);
// Restrict area and context, incompatibly - this has no results (and doesn't do a query).
$querydata
->
contextids
=
[
$contextc2f
->
id
];
$results
=
$this
->
search
->
search
(
$querydata
);
$this
->
assert_result_titles
([],
$results
);
}
/**
* Asserts that the returned documents have the expected titles (regardless of order).
*
* @param string[] $expected List of expected document titles
* @param \core_search\document[] $results List of returned documents
*/
protected
function
assert_result_titles
(
array
$expected
,
array
$results
)
{
$titles
=
[];
foreach
(
$results
as
$result
)
{
$titles
[]
=
$result
->
get
(
'title'
);
}
sort
(
$titles
);
sort
(
$expected
);
$this
->
assertEquals
(
$expected
,
$titles
);
}
}
search/index.php
View file @
97812f14
...
...
@@ -27,6 +27,7 @@ require_once(__DIR__ . '/../config.php');
$page
=
optional_param
(
'page'
,
0
,
PARAM_INT
);
$q
=
optional_param
(
'q'
,
''
,
PARAM_NOTAGS
);
$title
=
optional_param
(
'title'
,
''
,
PARAM_NOTAGS
);
$contextid
=
optional_param
(
'context'
,
0
,
PARAM_INT
);
// Moving areaids, courseids, timestart, and timeend further down as they might come as an array if they come from the form.
$context
=
context_system
::
instance
();
...
...
@@ -55,8 +56,23 @@ if (\core_search\manager::is_global_search_enabled() === false) {
$search
=
\
core_search\manager
::
instance
();
// We first get the submitted data as we want to set it all in the page URL.
$mform
=
new
\
core_search\output\form\search
(
null
,
array
(
'searchengine'
=>
$search
->
get_engine
()
->
get_plugin_name
()));
// Set up custom data for form.
$customdata
=
[
'searchengine'
=>
$search
->
get_engine
()
->
get_plugin_name
()];
if
(
$contextid
)
{
// When a context is supplied, check if it's within course level. If so, show dropdown.
$context
=
context
::
instance_by_id
(
$contextid
);
$coursecontext
=
$context
->
get_course_context
(
false
);
if
(
$coursecontext
)
{
$searchwithin
=
[];
$searchwithin
[
''
]
=
get_string
(
'everywhere'
,
'search'
);
$searchwithin
[
'course'
]
=
$coursecontext
->
get_context_name
();
if
(
$context
->
contextlevel
!==
CONTEXT_COURSE
)
{
$searchwithin
[
'context'
]
=
$context
->
get_context_name
();
}
$customdata
[
'searchwithin'
]
=
$searchwithin
;
}
}
$mform
=
new
\
core_search\output\form\search
(
null
,
$customdata
);
$data
=
$mform
->
get_data
();
if
(
!
$data
&&
$q
)
{
...
...
@@ -77,9 +93,25 @@ if (!$data && $q) {
}
$data
->
timestart
=
optional_param
(
'timestart'
,
0
,
PARAM_INT
);
$data
->
timeend
=
optional_param
(
'timeend'
,
0
,
PARAM_INT
);
$data
->
context
=
$contextid
;
$mform
->
set_data
(
$data
);
}
// Convert the 'search within' option, if used, to course or context restrictions.
if
(
$data
&&
!
empty
(
$data
->
searchwithin
))
{
switch
(
$data
->
searchwithin
)
{
case
'course'
:
$data
->
courseids
=
[
$coursecontext
->
instanceid
];
break
;
case
'context'
:
$data
->
courseids
=
[
$coursecontext
->
instanceid
];
$data
->
contextids
=
[
$context
->
id
];
break
;
}
}
// Set the page URL.
$urlparams
=
array
(
'page'
=>
$page
);
if
(
$data
)
{
...
...
search/tests/base_test.php
View file @
97812f14
...
...
@@ -106,6 +106,7 @@ class search_base_testcase extends advanced_testcase {
// Construct the search document.
$rec
=
new
\
stdClass
();
$rec
->
contextid
=
1
;
$area
=
new
core_mocksearch\search\mock_search_area
();
$record
=
$this
->
generator
->
create_record
(
$rec
);
$document
=
$area
->
get_document
(
$record
);
...
...
search/tests/behat/search_query.feature
View file @
97812f14
...
...
@@ -7,10 +7,13 @@ Feature: Use global search interface
Background
:
Given the following config values are set as admin
:
|
enableglobalsearch
|
1
|
And
the
following
"courses"
exist:
|
shortname
|
fullname
|
|
F1
|
Amphibians
|
And the following "activities" exist
:
|
activity
|
name
|
intro
|
course
|
idnumber
|
|
page
|
PageName1
|
PageDesc1
|
Acceptance
test
site
|
PAGE1
|
|
forum
|
ForumName1
|
ForumDesc1
|
Acceptance
test
site
|
FORUM1
|
|
activity
|
name
|
intro
|
course
|
idnumber
|
|
page
|
PageName1
|
PageDesc1
|
F1
|
PAGE1
|
|
forum
|
ForumName1
|
ForumDesc1
|
F1
|
FORUM1
|
And
I log in as
"admin"
@javascript
...
...
@@ -47,3 +50,44 @@ Feature: Use global search interface
# Check the link works.
And
I follow
"ForumName1"
And
I should see
"ForumName1"
in the
".breadcrumb"
"css_element"
@javascript
Scenario
:
Search starting from site context (no within option)
Given global search expects the query "frogs" and will return
:
|
type
|
idnumber
|
|
activity
|
PAGE1
|
When
I search for
"frogs"
using the header global search box
And
I expand all fieldsets
Then
I should not see
"Search within"
And
I should see
"Courses"
@javascript
Scenario
:
Search starting from course context (within option lists course)
Given global search expects the query "frogs" and will return
:
|
type
|
idnumber
|
|
activity
|
PAGE1
|
When
I am on
"Amphibians"
course homepage
And
I search for
"frogs"
using the header global search box
And
I expand all fieldsets
Then
I should see
"Search within"
And
I select
"Everywhere you can access"
from the
"Search within"
singleselect
And
I should see
"Courses"
And I select "Course
:
Amphibians"
from
the
"Search
within"
singleselect
And
I should not see
"Courses"
@javascript
Scenario
:
Search starting from forum context (within option lists course and forum)
Given global search expects the query "frogs" and will return
:
|
type
|
idnumber
|
|
activity
|
PAGE1
|
When
I am on
"Amphibians"
course homepage
And
I follow
"ForumName1"
And
I search for
"frogs"
using the header global search box
And
I expand all fieldsets
And
I should see
"Search within"
And
I select
"Everywhere you can access"
from the
"Search within"
singleselect
And
I should see
"Courses"
And I select "Course
:
Amphibians"
from
the
"Search
within"
singleselect
And
I should not see
"Courses"
And I select "Forum
:
ForumName1"
from
the
"Search
within"
singleselect
And
I should not see
"Courses"
search/tests/fixtures/mock_search_area.php
View file @
97812f14
...
...
@@ -36,7 +36,7 @@ class mock_search_area extends \core_search\base {
* Multiple context level so we can test get_areas_user_accesses.
* @var int[]
*/
protected
static
$levels
=
[
CONTEXT_
SYSTEM
,
CONTEXT_USER
];
protected
static
$levels
=
[
CONTEXT_
COURSE
,
CONTEXT_USER
];
/**
* To make things easier, base class required config stuff.
...
...
search/tests/fixtures/testable_core_search.php
View file @
97812f14
...
...
@@ -72,8 +72,8 @@ class testable_core_search extends \core_search\manager {
*
* @return array
*/
public
function
get_areas_user_accesses
(
$limitcourseids
=
false
)
{
return
parent
::
get_areas_user_accesses
(
$limitcourseids
);
public
function
get_areas_user_accesses
(
$limitcourseids
=
false
,
$limitcontextids
=
false
)
{
return
parent
::
get_areas_user_accesses
(
$limitcourseids
,
$limitcontextids
);
}
/**
...
...
search/tests/generator/lib.php
View file @
97812f14
...
...
@@ -118,7 +118,7 @@ class core_search_generator extends component_generator_base {
}
if
(
!
isset
(
$options
->
contextid
))
{
$info
->
contextid
=
\
context_
system
::
instance
()
->
id
;
$info
->
contextid
=
\
context_
course
::
instance
(
SITEID
)
->
id
;
}
else
{
$info
->
contextid
=
$options
->
contextid
;
}
...
...
search/tests/manager_test.php
View file @
97812f14
...
...
@@ -526,6 +526,7 @@ class search_manager_testcase extends advanced_testcase {
$this
->
resetAfterTest
();
$frontpage
=
$DB
->
get_record
(
'course'
,
array
(
'id'
=>
SITEID
));
$frontpagectx
=
context_course
::
instance
(
$frontpage
->
id
);
$course1
=
$this
->
getDataGenerator
()
->
create_course
();
$course1ctx
=
context_course
::
instance
(
$course1
->
id
);
$course2
=
$this
->
getDataGenerator
()
->
create_course
();
...
...
@@ -557,14 +558,13 @@ class search_manager_testcase extends advanced_testcase {
$this
->
assertTrue
(
$search
->
get_areas_user_accesses
());
$sitectx
=
\
context_course
::
instance
(
SITEID
);
$systemctxid
=
\
context_system
::
instance
()
->
id
;
// Can access the frontpage ones.
$this
->
setUser
(
$noaccess
);
$contexts
=
$search
->
get_areas_user_accesses
();
$this
->
assertEquals
(
array
(
$frontpageforumcontext
->
id
=>
$frontpageforumcontext
->
id
),
$contexts
[
$this
->
forumpostareaid
]);
$this
->
assertEquals
(
array
(
$sitectx
->
id
=>
$sitectx
->
id
),
$contexts
[
$this
->
mycoursesareaid
]);
$mockctxs
=
array
(
$noaccessctx
->
id
=>
$noaccessctx
->
id
,
$
system
ctxid
=>
$
system
ctxid
);
$mockctxs
=
array
(
$noaccessctx
->
id
=>
$noaccessctx
->
id
,
$
frontpage
ctx
->
id
=>
$
frontpage
ctx
->
id
);
$this
->
assertEquals
(
$mockctxs
,
$contexts
[
$mockareaid
]);
$this
->
setUser
(
$teacher
);
...
...
@@ -574,7 +574,8 @@ class search_manager_testcase extends advanced_testcase {
$this
->
assertEquals
(
$frontpageandcourse1
,
$contexts
[
$this
->
forumpostareaid
]);
$this
->
assertEquals
(
array
(
$sitectx
->
id
=>
$sitectx
->
id
,
$course1ctx
->
id
=>
$course1ctx
->
id
),
$contexts
[
$this
->
mycoursesareaid
]);
$mockctxs
=
array
(
$teacherctx
->
id
=>
$teacherctx
->
id
,
$systemctxid
=>
$systemctxid
);
$mockctxs
=
array
(
$teacherctx
->
id
=>
$teacherctx
->
id
,
$frontpagectx
->
id
=>
$frontpagectx
->
id
,
$course1ctx
->
id
=>
$course1ctx
->
id
);
$this
->
assertEquals
(
$mockctxs
,
$contexts
[
$mockareaid
]);
$this
->
setUser
(
$student
);
...
...
@@ -582,7 +583,8 @@ class search_manager_testcase extends advanced_testcase {
$this
->
assertEquals
(
$frontpageandcourse1
,
$contexts
[
$this
->
forumpostareaid
]);
$this
->
assertEquals
(
array
(
$sitectx
->
id
=>
$sitectx
->
id
,
$course1ctx
->
id
=>
$course1ctx
->
id
),
$contexts
[
$this
->
mycoursesareaid
]);
$mockctxs
=
array
(
$studentctx
->
id
=>
$studentctx
->
id
,
$systemctxid
=>
$systemctxid
);
$mockctxs
=
array
(
$studentctx
->
id
=>
$studentctx
->
id
,
$frontpagectx
->
id
=>
$frontpagectx
->
id
,
$course1ctx
->
id
=>
$course1ctx
->
id
);
$this
->
assertEquals
(
$mockctxs
,
$contexts
[
$mockareaid
]);
// Hide the activity.
...
...
@@ -616,6 +618,32 @@ class search_manager_testcase extends advanced_testcase {
$allcontexts
=
array
(
$context1
->
id
=>
$context1
->
id
,
$context2
->
id
=>
$context2
->
id
);
$this
->
assertEquals
(
$allcontexts
,
$contexts
[
$this
->
forumpostareaid
]);
$this
->
assertEquals
(
array
(
$course1ctx
->
id
=>
$course1ctx
->
id
),
$contexts
[
$this
->
mycoursesareaid
]);
// Test context limited search with no course limit.
$contexts
=
$search
->
get_areas_user_accesses
(
false
,
[
$frontpageforumcontext
->
id
,
$course2ctx
->
id
]);
$this
->
assertEquals
([
$frontpageforumcontext
->
id
=>
$frontpageforumcontext
->
id
],
$contexts
[
$this
->
forumpostareaid
]);
$this
->
assertEquals
([
$course2ctx
->
id
=>
$course2ctx
->
id
],
$contexts
[
$this
->
mycoursesareaid
]);
// Test context limited search with course limit.
$contexts
=
$search
->
get_areas_user_accesses
([
$course1
->
id
,
$course2
->
id
],
[
$frontpageforumcontext
->
id
,
$course2ctx
->
id
]);
$this
->
assertArrayNotHasKey
(
$this
->
forumpostareaid
,
$contexts
);
$this
->
assertEquals
([
$course2ctx
->
id
=>
$course2ctx
->
id
],
$contexts
[
$this
->
mycoursesareaid
]);
// Single context and course.
$contexts
=
$search
->
get_areas_user_accesses
([
$course1
->
id
],
[
$context1
->
id
]);
$this
->
assertEquals
([
$context1
->
id
=>
$context1
->
id
],
$contexts
[
$this
->
forumpostareaid
]);
$this
->
assertArrayNotHasKey
(
$this
->
mycoursesareaid
,
$contexts
);
// For admins, this is still limited only if we specify the things, so it should be same.