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
moodle
moodle
Commits
01783146
Commit
01783146
authored
Mar 24, 2017
by
Andrew Hancox
Committed by
Marina Glancy
Apr 21, 2017
Browse files
MDL-57457 mod_book: Implement tagging
parent
8e965537
Changes
14
Hide whitespace changes
Inline
Side-by-side
mod/book/backup/moodle2/backup_book_stepslib.php
View file @
01783146
...
...
@@ -31,6 +31,9 @@ class backup_book_activity_structure_step extends backup_activity_structure_step
protected
function
define_structure
()
{
// To know if we are including userinfo.
$userinfo
=
$this
->
get_setting_value
(
'userinfo'
);
// Define each element separated.
$book
=
new
backup_nested_element
(
'book'
,
array
(
'id'
),
array
(
'name'
,
'intro'
,
'introformat'
,
'numbering'
,
'navstyle'
,
...
...
@@ -40,6 +43,9 @@ class backup_book_activity_structure_step extends backup_activity_structure_step
'pagenum'
,
'subchapter'
,
'title'
,
'content'
,
'contentformat'
,
'hidden'
,
'timemcreated'
,
'timemodified'
,
'importsrc'
));
$tags
=
new
backup_nested_element
(
'tags'
);
$tag
=
new
backup_nested_element
(
'tag'
,
array
(
'id'
),
array
(
'name'
,
'rawname'
));
$book
->
add_child
(
$chapters
);
$chapters
->
add_child
(
$chapter
);
...
...
@@ -51,6 +57,22 @@ class backup_book_activity_structure_step extends backup_activity_structure_step
$book
->
annotate_files
(
'mod_book'
,
'intro'
,
null
);
// This file area hasn't itemid
$chapter
->
annotate_files
(
'mod_book'
,
'chapter'
,
'id'
);
$chapter
->
add_child
(
$tags
);
$tags
->
add_child
(
$tag
);
// All these source definitions only happen if we are including user info.
if
(
$userinfo
)
{
$tag
->
set_source_sql
(
'SELECT t.id, t.name, t.rawname
FROM {tag} t
JOIN {tag_instance} ti ON ti.tagid = t.id
WHERE ti.itemtype = ?
AND ti.component = ?
AND ti.itemid = ?'
,
array
(
backup_helper
::
is_sqlparam
(
'book_chapters'
),
backup_helper
::
is_sqlparam
(
'mod_book'
),
backup
::
VAR_PARENTID
));
}
// Return the root element (book), wrapped into standard activity structure
return
$this
->
prepare_activity_structure
(
$book
);
}
...
...
mod/book/backup/moodle2/restore_book_stepslib.php
View file @
01783146
...
...
@@ -30,12 +30,16 @@ defined('MOODLE_INTERNAL') || die;
class
restore_book_activity_structure_step
extends
restore_activity_structure_step
{
protected
function
define_structure
()
{
$paths
=
array
();
$userinfo
=
$this
->
get_setting_value
(
'userinfo'
);
$paths
[]
=
new
restore_path_element
(
'book'
,
'/activity/book'
);
$paths
[]
=
new
restore_path_element
(
'book_chapter'
,
'/activity/book/chapters/chapter'
);
if
(
$userinfo
)
{
$paths
[]
=
new
restore_path_element
(
'book_tag'
,
'/activity/book/chapters/chapter/tags/tag'
);
}
// Return the paths wrapped into standard activity structure
return
$this
->
prepare_activity_structure
(
$paths
);
}
...
...
@@ -72,6 +76,20 @@ class restore_book_activity_structure_step extends restore_activity_structure_st
$this
->
set_mapping
(
'book_chapter'
,
$oldid
,
$newitemid
,
true
);
}
protected
function
process_book_tag
(
$data
)
{
$data
=
(
object
)
$data
;
if
(
!
core_tag_tag
::
is_enabled
(
'mod_book'
,
'book_chapters'
))
{
// Tags disabled in server, nothing to process.
return
;
}
$tag
=
$data
->
rawname
;
$itemid
=
$this
->
get_new_parentid
(
'book_chapter'
);
$context
=
context_module
::
instance
(
$this
->
task
->
get_moduleid
());
core_tag_tag
::
add_item_tag
(
'mod_book'
,
'book_chapters'
,
$itemid
,
$context
,
$tag
);
}
protected
function
after_execute
()
{
global
$DB
;
...
...
mod/book/db/tag.php
0 → 100644
View file @
01783146
<?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/>.
/**
* Tag areas in component mod_book
*
* @package mod_book
* @copyright 2017 Andrew Hancox <andrewdchancox@googlemail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined
(
'MOODLE_INTERNAL'
)
||
die
();
$tagareas
=
array
(
array
(
'itemtype'
=>
'book_chapters'
,
'component'
=>
'mod_book'
,
'callback'
=>
'mod_book_get_tagged_chapters'
,
'callbackfile'
=>
'/mod/book/locallib.php'
,
),
);
mod/book/delete.php
View file @
01783146
...
...
@@ -65,6 +65,7 @@ if ($confirm) {
break
;
}
else
{
// This is subchapter of the chapter being removed.
core_tag_tag
::
remove_all_item_tags
(
'mod_book'
,
'book_chapters'
,
$ch
->
id
);
$fs
->
delete_area_files
(
$context
->
id
,
'mod_book'
,
'chapter'
,
$ch
->
id
);
$DB
->
delete_records
(
'book_chapters'
,
[
'id'
=>
$ch
->
id
]);
\
mod_book\event\chapter_deleted
::
create_from_chapter
(
$book
,
$context
,
$ch
)
->
trigger
();
...
...
@@ -76,6 +77,7 @@ if ($confirm) {
}
// Now delete the actual chapter.
core_tag_tag
::
remove_all_item_tags
(
'mod_book'
,
'book_chapters'
,
$chapter
->
id
);
$fs
->
delete_area_files
(
$context
->
id
,
'mod_book'
,
'chapter'
,
$chapter
->
id
);
$DB
->
delete_records
(
'book_chapters'
,
[
'id'
=>
$chapter
->
id
]);
...
...
mod/book/edit.php
View file @
01783146
...
...
@@ -75,9 +75,9 @@ if ($mform->is_cancelled()) {
$DB
->
update_record
(
'book_chapters'
,
$data
);
$DB
->
set_field
(
'book'
,
'revision'
,
$book
->
revision
+
1
,
array
(
'id'
=>
$book
->
id
));
$chapter
=
$DB
->
get_record
(
'book_chapters'
,
array
(
'id'
=>
$data
->
id
));
core_tag_tag
::
set_item_tags
(
'mod_book'
,
'book_chapters'
,
$chapter
->
id
,
$context
,
$data
->
tags
);
\
mod_book\event\chapter_updated
::
create_from_chapter
(
$book
,
$context
,
$chapter
)
->
trigger
();
}
else
{
// adding new chapter
$data
->
bookid
=
$book
->
id
;
...
...
@@ -102,6 +102,10 @@ if ($mform->is_cancelled()) {
$DB
->
set_field
(
'book'
,
'revision'
,
$book
->
revision
+
1
,
array
(
'id'
=>
$book
->
id
));
$chapter
=
$DB
->
get_record
(
'book_chapters'
,
array
(
'id'
=>
$data
->
id
));
if
(
core_tag_tag
::
is_enabled
(
'mod_book'
,
'book_chapters'
)
&&
isset
(
$data
->
tags
))
{
core_tag_tag
::
set_item_tags
(
'mod_book'
,
'book_chapters'
,
$chapter
->
id
,
$context
,
$data
->
tags
);
}
\
mod_book\event\chapter_created
::
create_from_chapter
(
$book
,
$context
,
$chapter
)
->
trigger
();
}
...
...
@@ -120,6 +124,11 @@ if ($chapters = book_preload_chapters($book)) {
echo
$OUTPUT
->
header
();
echo
$OUTPUT
->
heading
(
$book
->
name
);
$mform
->
display
();
if
(
core_tag_tag
::
is_enabled
(
'mod_book'
,
'book_chapters'
))
{
$data
=
new
StdClass
();
$data
->
tags
=
core_tag_tag
::
get_item_tags_array
(
'mod_book'
,
'book_chapters'
,
$chapter
->
id
);
$mform
->
set_data
(
$data
);
$mform
->
display
();
}
echo
$OUTPUT
->
footer
();
mod/book/edit_form.php
View file @
01783146
...
...
@@ -58,6 +58,13 @@ class book_chapter_edit_form extends moodleform {
$mform
->
setType
(
'content_editor'
,
PARAM_RAW
);
$mform
->
addRule
(
'content_editor'
,
get_string
(
'required'
),
'required'
,
null
,
'client'
);
if
(
core_tag_tag
::
is_enabled
(
'mod_book'
,
'book_chapters'
))
{
$mform
->
addElement
(
'header'
,
'tagshdr'
,
get_string
(
'tags'
,
'tag'
));
$mform
->
addElement
(
'tags'
,
'tags'
,
get_string
(
'tags'
),
array
(
'itemtype'
=>
'book_chapters'
,
'component'
=>
'mod_book'
));
}
$mform
->
addElement
(
'hidden'
,
'id'
);
$mform
->
setType
(
'id'
,
PARAM_INT
);
...
...
mod/book/lang/en/book.php
View file @
01783146
...
...
@@ -100,3 +100,8 @@ $string['page-mod-book-x'] = 'Any book module page';
$string
[
'subchapternotice'
]
=
'(Only available once the first chapter has been created)'
;
$string
[
'subplugintype_booktool'
]
=
'Book tool'
;
$string
[
'subplugintype_booktool_plural'
]
=
'Book tools'
;
$string
[
'removeallbooktags'
]
=
'Remove all book tags'
;
$string
[
'tagarea_book_chapters'
]
=
'Book chapters'
;
$string
[
'tagsdeleted'
]
=
'Book tags have been deleted'
;
$string
[
'tagtitle'
]
=
'See the "{$a}" tag'
;
mod/book/locallib.php
View file @
01783146
...
...
@@ -417,6 +417,120 @@ function book_get_toc($chapters, $chapter, $book, $cm, $edit) {
return
$toc
;
}
/**
* Returns book chapters tagged with a specified tag.
*
* This is a callback used by the tag area mod_book/book_chapters to search for book chapters
* tagged with a specific tag.
*
* @param core_tag_tag $tag
* @param bool $exclusivemode if set to true it means that no other entities tagged with this tag
* are displayed on the page and the per-page limit may be bigger
* @param int $fromctx context id where the link was displayed, may be used by callbacks
* to display items in the same context first
* @param int $ctx context id where to search for records
* @param bool $rec search in subcontexts as well
* @param int $page 0-based number of page being displayed
* @return \core_tag\output\tagindex
*/
function
mod_book_get_tagged_chapters
(
$tag
,
$exclusivemode
=
false
,
$fromctx
=
0
,
$ctx
=
0
,
$rec
=
true
,
$page
=
0
)
{
global
$OUTPUT
;
$perpage
=
$exclusivemode
?
20
:
5
;
// Build the SQL query.
$ctxselect
=
context_helper
::
get_preload_record_columns_sql
(
'ctx'
);
$query
=
"SELECT bc.id, bc.title, bc.bookid, bc.hidden,
cm.id AS cmid, c.id AS courseid, c.shortname, c.fullname,
$ctxselect
FROM
{
book_chapters
}
bc
JOIN
{
book
}
b ON b.id = bc.bookid
JOIN
{
modules
}
m ON m.name='book'
JOIN
{
course_modules
}
cm ON cm.module = m.id AND cm.instance = b.id
JOIN
{
tag_instance
}
tt ON bc.id = tt.itemid
JOIN
{
course
}
c ON cm.course = c.id
JOIN
{
context
}
ctx ON ctx.instanceid = cm.id AND ctx.contextlevel = :coursemodulecontextlevel
WHERE tt.itemtype = :itemtype AND tt.tagid = :tagid AND tt.component = :component
AND cm.deletioninprogress = 0
AND bc.id %ITEMFILTER% AND c.id %COURSEFILTER%"
;
$params
=
array
(
'itemtype'
=>
'book_chapters'
,
'tagid'
=>
$tag
->
id
,
'component'
=>
'mod_book'
,
'coursemodulecontextlevel'
=>
CONTEXT_MODULE
);
if
(
$ctx
)
{
$context
=
$ctx
?
context
::
instance_by_id
(
$ctx
)
:
context_system
::
instance
();
$query
.
=
$rec
?
' AND (ctx.id = :contextid OR ctx.path LIKE :path)'
:
' AND ctx.id = :contextid'
;
$params
[
'contextid'
]
=
$context
->
id
;
$params
[
'path'
]
=
$context
->
path
.
'/%'
;
}
$query
.
=
" ORDER BY "
;
if
(
$fromctx
)
{
// In order-clause specify that modules from inside "fromctx" context should be returned first.
$fromcontext
=
context
::
instance_by_id
(
$fromctx
);
$query
.
=
' (CASE WHEN ctx.id = :fromcontextid OR ctx.path LIKE :frompath THEN 0 ELSE 1 END),'
;
$params
[
'fromcontextid'
]
=
$fromcontext
->
id
;
$params
[
'frompath'
]
=
$fromcontext
->
path
.
'/%'
;
}
$query
.
=
' c.sortorder, cm.id, bc.id'
;
$totalpages
=
$page
+
1
;
// Use core_tag_index_builder to build and filter the list of items.
$builder
=
new
core_tag_index_builder
(
'mod_book'
,
'book_chapters'
,
$query
,
$params
,
$page
*
$perpage
,
$perpage
+
1
);
while
(
$item
=
$builder
->
has_item_that_needs_access_check
())
{
context_helper
::
preload_from_record
(
$item
);
$courseid
=
$item
->
courseid
;
if
(
!
$builder
->
can_access_course
(
$courseid
))
{
$builder
->
set_accessible
(
$item
,
false
);
continue
;
}
$modinfo
=
get_fast_modinfo
(
$builder
->
get_course
(
$courseid
));
// Set accessibility of this item and all other items in the same course.
$builder
->
walk
(
function
(
$taggeditem
)
use
(
$courseid
,
$modinfo
,
$builder
)
{
if
(
$taggeditem
->
courseid
==
$courseid
)
{
$accessible
=
false
;
if
((
$cm
=
$modinfo
->
get_cm
(
$taggeditem
->
cmid
))
&&
$cm
->
uservisible
)
{
if
(
empty
(
$taggeditem
->
hidden
))
{
$accessible
=
true
;
}
else
{
$accessible
=
has_capability
(
'mod/book:viewhiddenchapters'
,
context_module
::
instance
(
$cm
->
id
));
}
}
$builder
->
set_accessible
(
$taggeditem
,
$accessible
);
}
});
}
$items
=
$builder
->
get_items
();
if
(
count
(
$items
)
>
$perpage
)
{
$totalpages
=
$page
+
2
;
// We don't need exact page count, just indicate that the next page exists.
array_pop
(
$items
);
}
// Build the display contents.
if
(
$items
)
{
$tagfeed
=
new
core_tag\output\tagfeed
();
foreach
(
$items
as
$item
)
{
context_helper
::
preload_from_record
(
$item
);
$modinfo
=
get_fast_modinfo
(
$item
->
courseid
);
$cm
=
$modinfo
->
get_cm
(
$item
->
cmid
);
$pageurl
=
new
moodle_url
(
'/mod/book/view.php'
,
array
(
'chapterid'
=>
$item
->
id
,
'b'
=>
$item
->
bookid
));
$pagename
=
format_string
(
$item
->
title
,
true
,
array
(
'context'
=>
context_module
::
instance
(
$item
->
cmid
)));
$pagename
=
html_writer
::
link
(
$pageurl
,
$pagename
);
$courseurl
=
course_get_url
(
$item
->
courseid
,
$cm
->
sectionnum
);
$cmname
=
html_writer
::
link
(
$cm
->
url
,
$cm
->
get_formatted_name
());
$coursename
=
format_string
(
$item
->
fullname
,
true
,
array
(
'context'
=>
context_course
::
instance
(
$item
->
courseid
)));
$coursename
=
html_writer
::
link
(
$courseurl
,
$coursename
);
$icon
=
html_writer
::
link
(
$pageurl
,
html_writer
::
empty_tag
(
'img'
,
array
(
'src'
=>
$cm
->
get_icon_url
())));
$tagfeed
->
add
(
$icon
,
$pagename
,
$cmname
.
'<br>'
.
$coursename
);
}
$content
=
$OUTPUT
->
render_from_template
(
'core_tag/tagfeed'
,
$tagfeed
->
export_for_template
(
$OUTPUT
));
return
new
core_tag\output\tagindex
(
$tag
,
'mod_book'
,
'book_chapters'
,
$content
,
$exclusivemode
,
$fromctx
,
$ctx
,
$rec
,
$page
,
$totalpages
);
}
}
/**
* File browsing support class
...
...
mod/book/tests/behat/edit_tags.feature
0 → 100644
View file @
01783146
@mod
@mod_book
@core_tag
@javascript
Feature
:
Edited book chapters handle tags correctly
In order to get book chapters properly labelled
As a user
I need to introduce the tags while editing
Background
:
Given the following "users" exist
:
|
username
|
firstname
|
lastname
|
email
|
|
teacher1
|
Teacher
|
1
|
teacher1@example.com
|
|
student1
|
Student
|
1
|
student1@example.com
|
And the following "courses" exist
:
|
fullname
|
shortname
|
format
|
|
Course
1
|
C1
|
topics
|
And the following "course enrolments" exist
:
|
user
|
course
|
role
|
|
teacher1
|
C1
|
editingteacher
|
|
student1
|
C1
|
student
|
And
I log in as
"teacher1"
And
I follow
"Course 1"
And
I turn editing mode on
And I add a "Book" to section "1" and I fill the form with
:
|
Name
|
Test
book
|
|
Description
|
A
book
about
dreams!
|
And
I log out
Scenario
:
Book chapter edition of custom tags works as expected
Given
I log in as
"teacher1"
And
I follow
"Course 1"
And
I follow
"Test book"
And I set the following fields to these values
:
|
Chapter
title
|
Dummy
first
chapter
|
|
Content
|
Dream
is
the
start
of
a
journey
|
|
Tags
|
Example,
Chapter,
Cool
|
And
I press
"Save changes"
Then
I should see
"Example"
in the
".book-tags"
"css_element"
And
I should see
"Chapter"
in the
".book-tags"
"css_element"
And
I should see
"Cool"
in the
".book-tags"
"css_element"
And
I press
"Turn editing on"
And
I follow
"Edit chapter \"
1. Dummy first chapter\""
Then
I should see
"Example"
in the
".form-autocomplete-selection"
"css_element"
Then
I should see
"Chapter"
in the
".form-autocomplete-selection"
"css_element"
Then
I should see
"Cool"
in the
".form-autocomplete-selection"
"css_element"
@javascript
Scenario
:
Book chapter edition of standard tags works as expected
Given
I log in as
"admin"
And
I navigate to
"Appearance > Manage tags"
in site administration
And
I follow
"Default collection"
And
I follow
"Add standard tags"
And
I set the field
"Enter comma-separated list of new tags"
to
"OT1, OT2, OT3"
And
I press
"Continue"
And
I log out
And
I log in as
"teacher1"
And
I follow
"Course 1"
And
I follow
"Test book"
And
I click on
".form-autocomplete-downarrow"
"css_element"
And
I should see
"OT1"
in the
".form-autocomplete-suggestions"
"css_element"
And
I should see
"OT2"
in the
".form-autocomplete-suggestions"
"css_element"
And
I should see
"OT3"
in the
".form-autocomplete-suggestions"
"css_element"
When I set the following fields to these values
:
|
Chapter
title
|
Dummy
first
chapter
|
|
Content
|
Dream
is
the
start
of
a
journey
|
|
Tags
|
OT1,
OT3
|
And
I press
"Save changes"
Then
I should see
"OT1"
in the
".book-tags"
"css_element"
And
I should see
"OT3"
in the
".book-tags"
"css_element"
And
I should not see
"OT2"
in the
".book-tags"
"css_element"
And
I press
"Turn editing on"
And
I follow
"Edit chapter \"
1. Dummy first chapter\""
And
I should see
"OT1"
in the
".form-autocomplete-selection"
"css_element"
And
I should see
"OT3"
in the
".form-autocomplete-selection"
"css_element"
And
I should not see
"OT2"
in the
".form-autocomplete-selection"
"css_element"
mod/book/tests/generator/lib.php
View file @
01783146
...
...
@@ -117,6 +117,14 @@ class mod_book_generator extends testing_module_generator {
WHERE id = ?"
;
$DB
->
execute
(
$sql
,
array
(
$record
->
bookid
));
if
(
property_exists
(
$record
,
'tags'
))
{
$cm
=
get_coursemodule_from_instance
(
'book'
,
$record
->
bookid
);
$tags
=
is_array
(
$record
->
tags
)
?
$record
->
tags
:
preg_split
(
'/,/'
,
$record
->
tags
);
core_tag_tag
::
set_item_tags
(
'mod_book'
,
'book_chapters'
,
$record
->
id
,
context_module
::
instance
(
$cm
->
id
),
$tags
);
}
return
$record
;
}
...
...
mod/book/tests/generator_test.php
View file @
01783146
...
...
@@ -62,10 +62,13 @@ class mod_book_generator_testcase extends advanced_testcase {
$bookgenerator
->
create_chapter
(
array
(
'bookid'
=>
$book
->
id
));
$this
->
assertTrue
(
$DB
->
record_exists
(
'book_chapters'
,
array
(
'bookid'
=>
$book
->
id
)));
$chapter
=
$bookgenerator
->
create_chapter
(
array
(
'bookid'
=>
$book
->
id
,
'content'
=>
'Yay!'
,
'title'
=>
'Oops'
));
$chapter
=
$bookgenerator
->
create_chapter
(
array
(
'bookid'
=>
$book
->
id
,
'content'
=>
'Yay!'
,
'title'
=>
'Oops'
,
'tags'
=>
array
(
'Cats'
,
'mice'
)));
$this
->
assertEquals
(
2
,
$DB
->
count_records
(
'book_chapters'
,
array
(
'bookid'
=>
$book
->
id
)));
$this
->
assertEquals
(
'Oops'
,
$DB
->
get_field_select
(
'book_chapters'
,
'title'
,
'id = :id'
,
array
(
'id'
=>
$chapter
->
id
)));
$this
->
assertEquals
(
'Yay!'
,
$DB
->
get_field_select
(
'book_chapters'
,
'content'
,
'id = :id'
,
array
(
'id'
=>
$chapter
->
id
)));
$this
->
assertEquals
(
array
(
'Cats'
,
'mice'
),
array_values
(
core_tag_tag
::
get_item_tags_array
(
'mod_book'
,
'book_chapters'
,
$chapter
->
id
)));
$chapter
=
$bookgenerator
->
create_content
(
$book
);
$this
->
assertEquals
(
3
,
$DB
->
count_records
(
'book_chapters'
,
array
(
'bookid'
=>
$book
->
id
)));
...
...
mod/book/tests/lib_test.php
View file @
01783146
...
...
@@ -236,4 +236,94 @@ class mod_book_lib_testcase extends advanced_testcase {
return
calendar_event
::
create
(
$event
);
}
public
function
test_mod_book_get_tagged_chapters
()
{
global
$DB
;
$this
->
resetAfterTest
();
$this
->
setAdminUser
();
// Setup test data.
$bookgenerator
=
$this
->
getDataGenerator
()
->
get_plugin_generator
(
'mod_book'
);
$course3
=
$this
->
getDataGenerator
()
->
create_course
();
$course2
=
$this
->
getDataGenerator
()
->
create_course
();
$course1
=
$this
->
getDataGenerator
()
->
create_course
();
$book1
=
$this
->
getDataGenerator
()
->
create_module
(
'book'
,
array
(
'course'
=>
$course1
->
id
));
$book2
=
$this
->
getDataGenerator
()
->
create_module
(
'book'
,
array
(
'course'
=>
$course2
->
id
));
$book3
=
$this
->
getDataGenerator
()
->
create_module
(
'book'
,
array
(
'course'
=>
$course3
->
id
));
$chapter11
=
$bookgenerator
->
create_content
(
$book1
,
array
(
'tags'
=>
array
(
'Cats'
,
'Dogs'
)));
$chapter12
=
$bookgenerator
->
create_content
(
$book1
,
array
(
'tags'
=>
array
(
'Cats'
,
'mice'
)));
$chapter13
=
$bookgenerator
->
create_content
(
$book1
,
array
(
'tags'
=>
array
(
'Cats'
)));
$chapter14
=
$bookgenerator
->
create_content
(
$book1
);
$chapter15
=
$bookgenerator
->
create_content
(
$book1
,
array
(
'tags'
=>
array
(
'Cats'
)));
$chapter16
=
$bookgenerator
->
create_content
(
$book1
,
array
(
'tags'
=>
array
(
'Cats'
),
'hidden'
=>
true
));
$chapter21
=
$bookgenerator
->
create_content
(
$book2
,
array
(
'tags'
=>
array
(
'Cats'
)));
$chapter22
=
$bookgenerator
->
create_content
(
$book2
,
array
(
'tags'
=>
array
(
'Cats'
,
'Dogs'
)));
$chapter23
=
$bookgenerator
->
create_content
(
$book2
,
array
(
'tags'
=>
array
(
'mice'
,
'Cats'
)));
$chapter31
=
$bookgenerator
->
create_content
(
$book3
,
array
(
'tags'
=>
array
(
'mice'
,
'Cats'
)));
$tag
=
core_tag_tag
::
get_by_name
(
0
,
'Cats'
);
// Admin can see everything.
$res
=
mod_book_get_tagged_chapters
(
$tag
,
/*$exclusivemode = */
false
,
/*$fromctx = */
0
,
/*$ctx = */
0
,
/*$rec = */
1
,
/*$chapter = */
0
);
$this
->
assertRegExp
(
'/'
.
$chapter11
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter12
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter13
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter14
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter15
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter16
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter21
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter22
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter23
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter31
->
title
.
'</'
,
$res
->
content
);
$this
->
assertEmpty
(
$res
->
prevpageurl
);
$this
->
assertNotEmpty
(
$res
->
nextpageurl
);
$res
=
mod_book_get_tagged_chapters
(
$tag
,
/*$exclusivemode = */
false
,
/*$fromctx = */
0
,
/*$ctx = */
0
,
/*$rec = */
1
,
/*$chapter = */
1
);
$this
->
assertNotRegExp
(
'/'
.
$chapter11
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter12
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter13
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter14
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter15
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter16
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter21
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter22
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter23
->
title
.
'</'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter31
->
title
.
'</'
,
$res
->
content
);
$this
->
assertNotEmpty
(
$res
->
prevpageurl
);
$this
->
assertEmpty
(
$res
->
nextpageurl
);
// Create and enrol a user.
$student
=
self
::
getDataGenerator
()
->
create_user
();
$studentrole
=
$DB
->
get_record
(
'role'
,
array
(
'shortname'
=>
'student'
));
$this
->
getDataGenerator
()
->
enrol_user
(
$student
->
id
,
$course1
->
id
,
$studentrole
->
id
,
'manual'
);
$this
->
getDataGenerator
()
->
enrol_user
(
$student
->
id
,
$course2
->
id
,
$studentrole
->
id
,
'manual'
);
$this
->
setUser
(
$student
);
core_tag_index_builder
::
reset_caches
();
// User can not see chapters in course 3 because he is not enrolled.
$res
=
mod_book_get_tagged_chapters
(
$tag
,
/*$exclusivemode = */
false
,
/*$fromctx = */
0
,
/*$ctx = */
0
,
/*$rec = */
1
,
/*$chapter = */
1
);
$this
->
assertRegExp
(
'/'
.
$chapter22
->
title
.
'/'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter23
->
title
.
'/'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter31
->
title
.
'/'
,
$res
->
content
);
// User can search book chapters inside a course.
$coursecontext
=
context_course
::
instance
(
$course1
->
id
);
$res
=
mod_book_get_tagged_chapters
(
$tag
,
/*$exclusivemode = */
false
,
/*$fromctx = */
0
,
/*$ctx = */
$coursecontext
->
id
,
/*$rec = */
1
,
/*$chapter = */
0
);
$this
->
assertRegExp
(
'/'
.
$chapter11
->
title
.
'/'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter12
->
title
.
'/'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter13
->
title
.
'/'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter14
->
title
.
'/'
,
$res
->
content
);
$this
->
assertRegExp
(
'/'
.
$chapter15
->
title
.
'/'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter21
->
title
.
'/'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter22
->
title
.
'/'
,
$res
->
content
);
$this
->
assertNotRegExp
(
'/'
.
$chapter23
->
title
.
'/'
,
$res
->
content
);
$this
->
assertEmpty
(
$res
->
nextpageurl
);
// User cannot see hidden chapters.
$this
->
assertNotRegExp
(
'/'
.
$chapter16
->
title
.
'/'
,
$res
->
content
);
}
}
mod/book/version.php
View file @
01783146
...
...
@@ -25,6 +25,6 @@
defined
(
'MOODLE_INTERNAL'
)
||
die
;
$plugin
->
component
=
'mod_book'
;
// Full name of the plugin (used for diagnostics)
$plugin
->
version
=
201612050
0
;
// The current module version (Date: YYYYMMDDXX)
$plugin
->
version
=
201612050
1
;
// The current module version (Date: YYYYMMDDXX)
$plugin
->
requires
=
2016112900
;
// Requires this Moodle version
$plugin
->
cron
=
0
;
// Period for cron to check this module (secs)
mod/book/view.php
View file @
01783146
...
...
@@ -237,6 +237,10 @@ echo format_text($chaptertext, $chapter->contentformat, array('noclean'=>true, '
echo
$OUTPUT
->
box_end
();
if
(
core_tag_tag
::
is_enabled
(
'mod_book'
,
'book_chapters'
))
{
echo
$OUTPUT
->
tag_list
(
core_tag_tag
::
get_item_tags
(
'mod_book'
,
'book_chapters'
,
$chapter
->
id
),
null
,
'book-tags'
);
}
if
(
$book
->
navstyle
)
{
// Lower navigation.
echo
'<div class="navbottom clearfix '
.
$navclasses
[
$book
->
navstyle
]
.
'">'
.
$chnavigation
.
'</div>'
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment