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
5f219cf1
Commit
5f219cf1
authored
Nov 13, 2015
by
Ben Kelada
Committed by
Ryan Wyllie
Jan 13, 2016
Browse files
MDL-372 forum: Improve pinning and update for Moodle 3.0
parent
87b007b4
Changes
22
Hide whitespace changes
Inline
Side-by-side
blocks/news_items/block_news_items.php
View file @
5f219cf1
...
...
@@ -93,7 +93,8 @@ class block_news_items extends block_base {
// descending order. The call to default sort order here will use
// that unless the discussion that post is in has a timestart set
// in the future.
$sort
=
forum_get_default_sort_order
(
true
,
'p.modified'
);
// This sort will ignore pinned posts as we want the most recent.
$sort
=
forum_get_default_sort_order
(
true
,
'p.modified'
,
'd'
,
false
);
if
(
!
$discussions
=
forum_get_discussions
(
$cm
,
$sort
,
false
,
$currentgroup
,
$this
->
page
->
course
->
newsitems
)
)
{
$text
.
=
'('
.
get_string
(
'nonews'
,
'forum'
)
.
')'
;
...
...
mod/forum/classes/event/discussion_pinned.php
View file @
5f219cf1
...
...
@@ -99,4 +99,25 @@ class discussion_pinned extends \core\event\base {
throw
new
\
coding_exception
(
'objectid must be set to the discussionid.'
);
}
}
/**
* Forum discussion object id mappings.
*
* @return array
*/
public
static
function
get_objectid_mapping
()
{
return
array
(
'db'
=>
'forum_discussions'
,
'restore'
=>
'forum_discussion'
);
}
/**
* Forum id mappings.
*
* @return array
*/
public
static
function
get_other_mapping
()
{
$othermapped
=
array
();
$othermapped
[
'forumid'
]
=
array
(
'db'
=>
'forum'
,
'restore'
=>
'forum'
);
return
$othermapped
;
}
}
mod/forum/classes/event/discussion_unpinned.php
View file @
5f219cf1
...
...
@@ -99,4 +99,25 @@ class discussion_unpinned extends \core\event\base {
throw
new
\
coding_exception
(
'objectid must be set to the discussionid.'
);
}
}
/**
* Forum discussion object id mappings.
*
* @return array
*/
public
static
function
get_objectid_mapping
()
{
return
array
(
'db'
=>
'forum_discussions'
,
'restore'
=>
'forum_discussion'
);
}
/**
* Forum id mappings.
*
* @return array
*/
public
static
function
get_other_mapping
()
{
$othermapped
=
array
();
$othermapped
[
'forumid'
]
=
array
(
'db'
=>
'forum'
,
'restore'
=>
'forum'
);
return
$othermapped
;
}
}
mod/forum/classes/post_form.php
View file @
5f219cf1
...
...
@@ -138,6 +138,11 @@ class mod_forum_post_form extends moodleform {
$mform
->
addHelpButton
(
'attachments'
,
'attachment'
,
'forum'
);
}
if
(
!
$post
->
parent
&&
has_capability
(
'mod/forum:pindiscussions'
,
$modcontext
))
{
$mform
->
addElement
(
'checkbox'
,
'pinned'
,
get_string
(
'discussionpinned'
,
'forum'
));
$mform
->
addHelpButton
(
'pinned'
,
'discussionpinned'
,
'forum'
);
}
if
(
empty
(
$post
->
id
)
&&
$manageactivities
)
{
$mform
->
addElement
(
'checkbox'
,
'mailnow'
,
get_string
(
'mailnow'
,
'forum'
));
}
...
...
mod/forum/db/access.php
View file @
5f219cf1
...
...
@@ -226,7 +226,7 @@ $capabilities = array(
'mod/forum:pindiscussions'
=>
array
(
'captype'
=>
'
read
'
,
'captype'
=>
'
write
'
,
'contextlevel'
=>
CONTEXT_MODULE
,
'archetypes'
=>
array
(
'teacher'
=>
CAP_ALLOW
,
...
...
mod/forum/db/install.xml
100644 → 100755
View file @
5f219cf1
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB
PATH=
"mod/forum/db"
VERSION=
"201
41028
"
COMMENT=
"XMLDB file for Moodle mod/forum"
<XMLDB
PATH=
"mod/forum/db"
VERSION=
"201
60113
"
COMMENT=
"XMLDB file for Moodle mod/forum"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation=
"../../../lib/xmldb/xmldb.xsd"
>
...
...
mod/forum/db/log.php
View file @
5f219cf1
...
...
@@ -26,21 +26,22 @@
defined
(
'MOODLE_INTERNAL'
)
||
die
();
global
$DB
;
// TODO: this is a hack, we should really do something with the SQL in SQL tables
global
$DB
;
// TODO: this is a hack, we should really do something with the SQL in SQL tables
.
$logs
=
array
(
array
(
'module'
=>
'forum'
,
'action'
=>
'add'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'update'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'add discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'add post'
,
'mtable'
=>
'forum_posts'
,
'field'
=>
'subject'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'update post'
,
'mtable'
=>
'forum_posts'
,
'field'
=>
'subject'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'user report'
,
'mtable'
=>
'user'
,
'field'
=>
$DB
->
sql_concat
(
'firstname'
,
"' '"
,
'lastname'
)),
array
(
'module'
=>
'forum'
,
'action'
=>
'move discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'view subscribers'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'view discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'view forum'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'subscribe'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'unsubscribe'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'pin discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'unpin discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'add'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'update'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'add discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'add post'
,
'mtable'
=>
'forum_posts'
,
'field'
=>
'subject'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'update post'
,
'mtable'
=>
'forum_posts'
,
'field'
=>
'subject'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'user report'
,
'mtable'
=>
'user'
,
'field'
=>
$DB
->
sql_concat
(
'firstname'
,
"' '"
,
'lastname'
)),
array
(
'module'
=>
'forum'
,
'action'
=>
'move discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'view subscribers'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'view discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'view forum'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'subscribe'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'unsubscribe'
,
'mtable'
=>
'forum'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'pin discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
array
(
'module'
=>
'forum'
,
'action'
=>
'unpin discussion'
,
'mtable'
=>
'forum_discussions'
,
'field'
=>
'name'
),
);
\ No newline at end of file
mod/forum/db/upgrade.php
View file @
5f219cf1
...
...
@@ -239,19 +239,6 @@ function xmldb_forum_upgrade($oldversion) {
// Moodle v2.8.0 release upgrade line.
// Put any upgrade step following this.
if
(
$oldversion
<
2014112400
)
{
// Add support for pinned discussions.
$table
=
new
xmldb_table
(
'forum_discussions'
);
$field
=
new
xmldb_field
(
'pinned'
,
XMLDB_TYPE_INTEGER
,
'1'
,
null
,
XMLDB_NOTNULL
,
null
,
'0'
,
'timeend'
);
if
(
!
$dbman
->
field_exists
(
$table
,
$field
))
{
$dbman
->
add_field
(
$table
,
$field
);
}
// Forum savepoint reached.
upgrade_mod_savepoint
(
true
,
2014112400
,
'forum'
);
}
// Moodle v2.9.0 release upgrade line.
// Put any upgrade step following this.
...
...
@@ -266,5 +253,18 @@ function xmldb_forum_upgrade($oldversion) {
// Moodle v3.0.0 release upgrade line.
// Put any upgrade step following this.
if
(
$oldversion
<
2015120800
)
{
// Add support for pinned discussions.
$table
=
new
xmldb_table
(
'forum_discussions'
);
$field
=
new
xmldb_field
(
'pinned'
,
XMLDB_TYPE_INTEGER
,
'1'
,
null
,
XMLDB_NOTNULL
,
null
,
'0'
,
'timeend'
);
if
(
!
$dbman
->
field_exists
(
$table
,
$field
))
{
$dbman
->
add_field
(
$table
,
$field
);
}
// Forum savepoint reached.
upgrade_mod_savepoint
(
true
,
2015120800
,
'forum'
);
}
return
true
;
}
mod/forum/discuss.php
View file @
5f219cf1
...
...
@@ -32,7 +32,7 @@ $mode = optional_param('mode', 0, PARAM_INT); // If set, changes the
$move
=
optional_param
(
'move'
,
0
,
PARAM_INT
);
// If set, moves this discussion to another forum
$mark
=
optional_param
(
'mark'
,
''
,
PARAM_ALPHA
);
// Used for tracking read posts if user initiated.
$postid
=
optional_param
(
'postid'
,
0
,
PARAM_INT
);
// Used for tracking read posts if user initiated.
$pin
=
optional_param
(
'pin'
,
-
1
,
PARAM_INT
);
// If set, pin or unpin this discussion.
$pin
=
optional_param
(
'pin'
,
-
1
,
PARAM_INT
);
// If set, pin or unpin this discussion.
$url
=
new
moodle_url
(
'/mod/forum/discuss.php'
,
array
(
'd'
=>
$d
));
if
(
$parent
!==
0
)
{
...
...
@@ -172,7 +172,6 @@ if ($move > 0 and confirm_sesskey()) {
redirect
(
$return
.
'&move=-1&sesskey='
.
sesskey
());
}
// Pin or unpin discussion if requested.
if
(
$pin
!==
-
1
&&
confirm_sesskey
())
{
require_capability
(
'mod/forum:pindiscussions'
,
$modcontext
);
...
...
@@ -181,19 +180,15 @@ if ($pin !== -1 && confirm_sesskey()) {
switch
(
$pin
)
{
case
FORUM_DISCUSSION_PINNED
:
$DB
->
set_field
(
'forum_discussions'
,
'pinned'
,
$pin
,
array
(
'id'
=>
$discussion
->
id
));
$event
=
\
mod_forum\event\discussion_pinned
::
create
(
$params
);
$event
->
add_record_snapshot
(
'forum_discussions'
,
$discussion
);
$event
->
trigger
();
// Pin the discussion and trigger discussion pinned event.
forum_discussion_pin
(
$modcontext
,
$forum
,
$discussion
);
break
;
case
FORUM_DISCUSSION_UNPINNED
:
$DB
->
set_field
(
'forum_discussions'
,
'pinned'
,
$pin
,
array
(
'id'
=>
$discussion
->
id
));
$event
=
\
mod_forum\event\discussion_unpinned
::
create
(
$params
);
$event
->
add_record_snapshot
(
'forum_discussions'
,
$discussion
);
$event
->
trigger
();
// Unpin the discussion and trigger discussion unpinned event.
forum_discussion_unpin
(
$modcontext
,
$forum
,
$discussion
);
break
;
default
:
echo
$OUTPUT
->
notfication
(
"Invalid value when attempting to pin/unpin discussion"
);
echo
$OUTPUT
->
not
i
fication
(
"Invalid value when attempting to pin/unpin discussion"
);
break
;
}
...
...
@@ -299,7 +294,7 @@ $neighbourlinks = $renderer->neighbouring_discussion_navigation($neighbours['pre
echo
$neighbourlinks
;
/// Print the controls across the top
echo
'<div class="discussioncontrols clearfix">'
;
echo
'<div class="discussioncontrols clearfix">
<div class="controlscontainer">
'
;
if
(
!
empty
(
$CFG
->
enableportfolios
)
&&
has_capability
(
'mod/forum:exportdiscussion'
,
$modcontext
))
{
require_once
(
$CFG
->
libdir
.
'/portfoliolib.php'
);
...
...
@@ -374,8 +369,8 @@ if (has_capability('mod/forum:pindiscussions', $modcontext)) {
echo
html_writer
::
tag
(
'div'
,
$OUTPUT
->
render
(
$button
),
array
(
'class'
=>
'discussioncontrol pindiscussion'
));
}
echo
'<div class="clearfloat"> </div>'
;
echo
"</div>"
;
echo
"</div>
</div>
"
;
if
(
!
empty
(
$forum
->
blockafter
)
&&
!
empty
(
$forum
->
blockperiod
))
{
$a
=
new
stdClass
();
...
...
@@ -386,7 +381,7 @@ if (!empty($forum->blockafter) && !empty($forum->blockperiod)) {
if
(
$forum
->
type
==
'qanda'
&&
!
has_capability
(
'mod/forum:viewqandawithoutposting'
,
$modcontext
)
&&
!
forum_user_has_posted
(
$forum
->
id
,
$discussion
->
id
,
$USER
->
id
))
{
echo
$OUTPUT
->
notification
(
get_string
(
'qandanotify'
,
'forum'
));
echo
$OUTPUT
->
notification
(
get_string
(
'qandanotify'
,
'forum'
));
}
if
(
$move
==
-
1
and
confirm_sesskey
())
{
...
...
mod/forum/externallib.php
View file @
5f219cf1
...
...
@@ -649,7 +649,7 @@ class mod_forum_external extends external_api {
// Check they have the view forum capability.
require_capability
(
'mod/forum:viewdiscussion'
,
$modcontext
,
null
,
true
,
'noviewdiscussionspermission'
,
'forum'
);
$sort
=
'd.'
.
$sortby
.
' '
.
$sortdirection
;
$sort
=
'
d.pinned DESC,
d.'
.
$sortby
.
' '
.
$sortdirection
;
$alldiscussions
=
forum_get_discussions
(
$cm
,
$sort
,
true
,
-
1
,
-
1
,
true
,
$page
,
$perpage
,
FORUM_POSTS_ALL_USER_GROUPS
);
if
(
$alldiscussions
)
{
...
...
@@ -801,7 +801,8 @@ class mod_forum_external extends external_api {
'userpictureurl'
=>
new
external_value
(
PARAM_URL
,
'Post author picture.'
),
'usermodifiedpictureurl'
=>
new
external_value
(
PARAM_URL
,
'Post modifier picture.'
),
'numreplies'
=>
new
external_value
(
PARAM_TEXT
,
'The number of replies in the discussion'
),
'numunread'
=>
new
external_value
(
PARAM_INT
,
'The number of unread discussions.'
)
'numunread'
=>
new
external_value
(
PARAM_INT
,
'The number of unread discussions.'
),
'pinned'
=>
new
external_value
(
PARAM_BOOL
,
'Is the discussion pinned'
)
),
'post'
)
),
...
...
@@ -1115,6 +1116,7 @@ class mod_forum_external extends external_api {
'name'
=>
new
external_value
(
PARAM_ALPHANUM
,
'The allowed keys (value format) are:
discussionsubscribe (bool); subscribe to the discussion?, default to true
discussionpinned (bool); is the discussion pinned, default to false
'
),
'value'
=>
new
external_value
(
PARAM_RAW
,
'The value of the option,
This param is validated in the external function.'
...
...
@@ -1151,7 +1153,8 @@ class mod_forum_external extends external_api {
));
// Validate options.
$options
=
array
(
'discussionsubscribe'
=>
true
'discussionsubscribe'
=>
true
,
'discussionpinned'
=>
false
);
foreach
(
$params
[
'options'
]
as
$option
)
{
$name
=
trim
(
$option
[
'name'
]);
...
...
@@ -1159,6 +1162,9 @@ class mod_forum_external extends external_api {
case
'discussionsubscribe'
:
$value
=
clean_param
(
$option
[
'value'
],
PARAM_BOOL
);
break
;
case
'discussionpinned'
:
$value
=
clean_param
(
$option
[
'value'
],
PARAM_BOOL
);
break
;
default
:
throw
new
moodle_exception
(
'errorinvalidparam'
,
'webservice'
,
''
,
$name
);
}
...
...
@@ -1210,6 +1216,11 @@ class mod_forum_external extends external_api {
$discussion
->
name
=
$discussion
->
subject
;
$discussion
->
timestart
=
0
;
$discussion
->
timeend
=
0
;
if
(
has_capability
(
'mod/forum:pindiscussions'
,
$context
)
&&
$options
[
'discussionpinned'
])
{
$discussion
->
pinned
=
FORUM_DISCUSSION_PINNED
;
}
else
{
$discussion
->
pinned
=
FORUM_DISCUSSION_UNPINNED
;
}
if
(
$discussionid
=
forum_add_discussion
(
$discussion
))
{
...
...
mod/forum/lang/en/forum.php
View file @
5f219cf1
...
...
@@ -139,7 +139,8 @@ $string['discussionname'] = 'Discussion name';
$string
[
'discussionnownotsubscribed'
]
=
'{$a->name} will NOT be notified of new posts in \'{$a->discussion}\' of \'{$a->forum}\''
;
$string
[
'discussionnowsubscribed'
]
=
'{$a->name} will be notified of new posts in \'{$a->discussion}\' of \'{$a->forum}\''
;
$string
[
'discussionpin'
]
=
'Pin'
;
$string
[
'discussionpinned'
]
=
'Pinned: {$a}'
;
$string
[
'discussionpinned'
]
=
'Pinned'
;
$string
[
'discussionpinned_help'
]
=
'Pinned discussions will appear at the top of a forum.'
;
$string
[
'discussionsubscribestop'
]
=
'I don\'t want to be notified of new posts in this discussion'
;
$string
[
'discussionsubscribestart'
]
=
'Send me notifications of new posts in this discussion'
;
$string
[
'discussionsubscription'
]
=
'Discussion subscription'
;
...
...
mod/forum/lib.php
View file @
5f219cf1
...
...
@@ -2596,7 +2596,7 @@ function forum_get_discussions($cm, $forumsort="", $fullpost=true, $unused=-1, $
}
$allnames
=
get_all_user_name_fields
(
true
,
'u'
);
$sql
=
"SELECT
$postdata
, d.name, d.timemodified, d.usermodified, d.groupid, d.timestart, d.timeend, d.pinned,
$allnames
,
$sql
=
"SELECT
$postdata
, d.name, d.timemodified, d.usermodified, d.groupid, d.timestart, d.timeend, d.pinned,
$allnames
,
u.email, u.picture, u.imagealt
$umfields
FROM
{
forum_discussions
}
d
JOIN
{
forum_posts
}
p ON p.discussion = d.id
...
...
@@ -2604,17 +2604,15 @@ function forum_get_discussions($cm, $forumsort="", $fullpost=true, $unused=-1, $
$umtable
WHERE d.forum = ? AND p.parent = 0
$timelimit
$groupselect
ORDER BY
pinned DESC,
$forumsort
"
;
ORDER BY
$forumsort
, d.id DESC
"
;
return
$DB
->
get_records_sql
(
$sql
,
$params
,
$limitfrom
,
$limitnum
);
}
/**
* Gets the neighbours (previous and next) of a discussion.
*
* The calculation is based on the timemodified of the discussion and does not handle
* the neighbours having an identical timemodified. The reason is that we do not have any
* other mean to sort the records, e.g. we cannot use IDs as a greater ID can have a lower
* timemodified.
* The calculation is based on the timemodified when time modified or time created is identical
* It will revert to using the ID to sort consistently. This is better tha skipping a discussion.
*
* For blog-style forums, the calculation is based on the original creation time of the
* blog post.
...
...
@@ -2623,8 +2621,6 @@ function forum_get_discussions($cm, $forumsort="", $fullpost=true, $unused=-1, $
* by the user, it simply uses it as a reference to find the neighbours. On the other hand,
* the returned neighbours are checked and are accessible to the current user.
*
* This function ignores whether a discussion is pinned.
*
* @param object $cm The CM record.
* @param object $discussion The discussion record.
* @param object $forum The forum instance record.
...
...
@@ -2680,78 +2676,82 @@ function forum_get_discussion_neighbours($cm, $discussion, $forum) {
}
}
if
(
$forum
->
type
===
'blog'
)
{
$params
[
'forumid'
]
=
$cm
->
instance
;
$params
[
'discid1'
]
=
$discussion
->
id
;
$params
[
'discid2'
]
=
$discussion
->
id
;
$sql
=
"SELECT d.id, d.name, d.timemodified, d.groupid, d.timestart, d.timeend
FROM
{
forum_discussions
}
d
JOIN
{
forum_posts
}
p ON d.firstpost = p.id
WHERE d.forum = :forumid
AND d.id <> :discid1
$timelimit
$groupselect
"
;
$params
[
'forumid'
]
=
$cm
->
instance
;
$params
[
'discid1'
]
=
$discussion
->
id
;
$params
[
'discid2'
]
=
$discussion
->
id
;
$params
[
'discid3'
]
=
$discussion
->
id
;
$params
[
'discid4'
]
=
$discussion
->
id
;
$params
[
'disctimecompare1'
]
=
$discussion
->
timemodified
;
$params
[
'disctimecompare2'
]
=
$discussion
->
timemodified
;
$params
[
'pinnedstate1'
]
=
(
int
)
$discussion
->
pinned
;
$params
[
'pinnedstate2'
]
=
(
int
)
$discussion
->
pinned
;
$params
[
'pinnedstate3'
]
=
(
int
)
$discussion
->
pinned
;
$params
[
'pinnedstate4'
]
=
(
int
)
$discussion
->
pinned
;
$sub
=
"SELECT pp.created
FROM
{
forum_discussions
}
dd
JOIN
{
forum_posts
}
pp ON dd.firstpost = pp.id
WHERE dd.id = :discid2"
;
$prevsql
=
$sql
.
" AND p.created < (
$sub
)
ORDER BY p.created DESC"
;
$sql
=
"SELECT d.id, d.name, d.timemodified, d.groupid, d.timestart, d.timeend
FROM
{
forum_discussions
}
d
JOIN
{
forum_posts
}
p ON d.firstpost = p.id
WHERE d.forum = :forumid
AND d.id <> :discid1
$timelimit
$groupselect
"
;
$comparefield
=
"d.timemodified"
;
$comparevalue
=
":disctimecompare1"
;
$comparevalue2
=
":disctimecompare2"
;
if
(
!
empty
(
$CFG
->
forum_enabletimedposts
))
{
// Here we need to take into account the release time (timestart)
// if one is set, of the neighbouring posts and compare it to the
// timestart or timemodified of *this* post depending on if the
// release date of this post is in the future or not.
// This stops discussions that appear later because of the
// timestart value from being buried under discussions that were
// made afterwards.
$comparefield
=
"CASE WHEN d.timemodified < d.timestart
THEN d.timestart ELSE d.timemodified END"
;
if
(
$discussion
->
timemodified
<
$discussion
->
timestart
)
{
// Normally we would just use the timemodified for sorting
// discussion posts. However, when timed discussions are enabled,
// then posts need to be sorted base on the later of timemodified
// or the release date of the post (timestart).
$params
[
'disctimecompare1'
]
=
$discussion
->
timestart
;
$params
[
'disctimecompare2'
]
=
$discussion
->
timestart
;
}
}
$orderbydesc
=
forum_get_default_sort_order
(
true
,
$comparefield
,
'd'
,
false
);
$orderbyasc
=
forum_get_default_sort_order
(
false
,
$comparefield
,
'd'
,
false
);
$nextsql
=
$sql
.
" AND p.created > (
$sub
)
ORDER BY p.created ASC"
;
if
(
$forum
->
type
===
'blog'
)
{
$subselect
=
"SELECT pp.created
FROM
{
forum_discussions
}
dd
JOIN
{
forum_posts
}
pp ON dd.firstpost = pp.id "
;
$neighbours
[
'prev'
]
=
$DB
->
get_record_sql
(
$prevsql
,
$params
,
IGNORE_MULTIPLE
)
;
$neighbours
[
'next'
]
=
$DB
->
get_record_sql
(
$nextsql
,
$params
,
IGNORE_MULTIPLE
)
;
$subselectwhere1
=
" WHERE dd.id = :discid3"
;
$subselectwhere2
=
" WHERE dd.id = :discid4"
;
}
else
{
$params
[
'forumid'
]
=
$cm
->
instance
;
$params
[
'discid'
]
=
$discussion
->
id
;
$params
[
'disctimemodified'
]
=
$discussion
->
timemodified
;
$comparefield
=
"p.created"
;
$sql
=
"SELECT d.id, d.name, d.timemodified, d.groupid, d.timestart, d.timeend
FROM
{
forum_discussions
}
d
WHERE d.forum = :forumid
AND d.id <> :discid
$timelimit
$groupselect
"
;
$sub1
=
$subselect
.
$subselectwhere1
;
$comparevalue
=
"(
$sub1
)"
;
if
(
empty
(
$CFG
->
forum_enabletimedposts
))
{
$prevsql
=
$sql
.
" AND d.timemodified < :disctimemodified"
;
$nextsql
=
$sql
.
" AND d.timemodified > :disctimemodified"
;
$sub2
=
$subselect
.
$subselectwhere2
;
$comparevalue2
=
"(
$sub2
)"
;
}
else
{
// Normally we would just use the timemodified for sorting
// discussion posts. However, when timed discussions are enabled,
// then posts need to be sorted base on the later of timemodified
// or the release date of the post (timestart).
$params
[
'disctimecompare'
]
=
$discussion
->
timemodified
;
if
(
$discussion
->
timemodified
<
$discussion
->
timestart
)
{
$params
[
'disctimecompare'
]
=
$discussion
->
timestart
;
}
$orderbydesc
=
"d.pinned, p.created DESC"
;
$orderbyasc
=
"d.pinned, p.created ASC"
;
}
// Here we need to take into account the release time (timestart)
// if one is set, of the neighbouring posts and compare it to the
// timestart or timemodified of *this* post depending on if the
// release date of this post is in the future or not.
// This stops discussions that appear later because of the
// timestart value from being buried under discussions that were
// made afterwards.
$prevsql
=
$sql
.
" AND CASE WHEN d.timemodified < d.timestart
THEN d.timestart ELSE d.timemodified END < :disctimecompare"
;
$nextsql
=
$sql
.
" AND CASE WHEN d.timemodified < d.timestart
THEN d.timestart ELSE d.timemodified END > :disctimecompare"
;
}
$prevsql
.
=
' ORDER BY '
.
forum_get_default_sort_order
();
$nextsql
.
=
' ORDER BY '
.
forum_get_default_sort_order
(
false
);
$prevsql
=
$sql
.
" AND ( ((
$comparefield
<
$comparevalue
) AND :pinnedstate1 = d.pinned)
OR (
$comparefield
=
$comparevalue2
AND (d.pinned = 0 OR d.pinned = :pinnedstate4) AND d.id < :discid2)
OR (d.pinned = 0 AND d.pinned <> :pinnedstate2))
ORDER BY CASE WHEN d.pinned = :pinnedstate3 THEN 1 ELSE 0 END DESC,
$orderbydesc
, d.id DESC"
;
$neighbours
[
'prev'
]
=
$DB
->
get_record_sql
(
$prevsql
,
$params
,
IGNORE_MULTIPLE
);
$neighbours
[
'next'
]
=
$DB
->
get_record_sql
(
$nextsql
,
$params
,
IGNORE_MULTIPLE
);
}
$nextsql
=
$sql
.
" AND ( ((
$comparefield
>
$comparevalue
) AND :pinnedstate1 = d.pinned)
OR (
$comparefield
=
$comparevalue2
AND (d.pinned = 1 OR d.pinned = :pinnedstate4) AND d.id > :discid2)
OR (d.pinned = 1 AND d.pinned <> :pinnedstate2))
ORDER BY CASE WHEN d.pinned = :pinnedstate3 THEN 1 ELSE 0 END DESC,
$orderbyasc
, d.id ASC"
;
$neighbours
[
'prev'
]
=
$DB
->
get_record_sql
(
$prevsql
,
$params
,
IGNORE_MULTIPLE
);
$neighbours
[
'next'
]
=
$DB
->
get_record_sql
(
$nextsql
,
$params
,
IGNORE_MULTIPLE
);
return
$neighbours
;
}
...
...
@@ -2763,9 +2763,10 @@ function forum_get_discussion_neighbours($cm, $discussion, $forum) {
* @param bool $desc True for DESC, False for ASC.
* @param string $compare The field in the SQL to compare to normally sort by.
* @param string $prefix The prefix being used for the discussion table.
* @param bool $pinned sort pinned posts to the top
* @return string
*/
function
forum_get_default_sort_order
(
$desc
=
true
,
$compare
=
'd.timemodified'
,
$prefix
=
'd'
)
{
function
forum_get_default_sort_order
(
$desc
=
true
,
$compare
=
'd.timemodified'
,
$prefix
=
'd'
,
$pinned
=
true
)
{
global
$CFG
;
if
(
!
empty
(
$prefix
))
{
...
...
@@ -2774,6 +2775,12 @@ function forum_get_default_sort_order($desc = true, $compare = 'd.timemodified',
$dir
=
$desc
?
'DESC'
:
'ASC'
;
if
(
$pinned
==
true
)
{
$pinned
=
"
{
$prefix
}
pinned DESC,"
;
}
else
{
$pinned
=
''
;
}
$sort
=
"
{
$prefix
}
timemodified"
;
if
(
!
empty
(
$CFG
->
forum_enabletimedposts
))
{
$sort
=
"CASE WHEN
{
$compare
}
<
{
$prefix
}
timestart
...
...
@@ -2781,7 +2788,7 @@ function forum_get_default_sort_order($desc = true, $compare = 'd.timemodified',
ELSE
{
$compare
}
END"
;
}
return
"
$sort
$dir
"
;
return
"
$pinned
$sort
$dir
"
;
}
/**
...
...
@@ -3642,7 +3649,9 @@ function forum_print_discussion_header(&$post, $forum, $group = -1, $datestring
$topicclass
.
=
' pinned'
;
}
echo
'<td class="'
.
$topicclass
.
'">'
;
if
(
FORUM_DISCUSSION_PINNED
==
$post
->
pinned
)
{
echo
$OUTPUT
->
pix_icon
(
'i/pinned'
,
get_string
(
'discussionpinned'
,
'forum'
),
'mod_forum'
);
}
$canalwaysseetimedpost
=
$USER
->
id
==
$post
->
userid
||
$canviewhiddentimedposts
;
if
(
$timeddiscussion
&&
$canalwaysseetimedpost
)
{
echo
$PAGE
->
get_renderer
(
'mod_forum'
)
->
timed_discussion_tooltip
(
$post
,
empty
(
$timedoutsidewindow
));
...
...
@@ -4358,6 +4367,10 @@ function forum_update_post($post, $mform, &$message) {
$discussion
->
name
=
$post
->
subject
;
$discussion
->
timestart
=
$post
->
timestart
;
$discussion
->
timeend
=
$post
->
timeend
;
if
(
isset
(
$post
->
pinned
))
{
$discussion
->
pinned
=
$post
->
pinned
;
}
}
$post
->
message
=
file_save_draft_area_files
(
$post
->
itemid
,
$context
->
id
,
'mod_forum'
,
'post'
,
$post
->
id
,
mod_forum_post_form
::
editor_options
(
$context
,
$post
->
id
),
$post
->
message
);
...
...
@@ -4390,7 +4403,7 @@ function forum_update_post($post, $mform, &$message) {
function
forum_add_discussion
(
$discussion
,
$mform
=
null
,
$unused
=
null
,
$userid
=
null
)
{
global
$USER
,
$CFG
,
$DB
;
$timenow
=
time
();
$timenow
=
isset
(
$discussion
->
timenow
)
?
$discussion
->
timenow
:
time
();
if
(
is_null
(
$userid
))
{
$userid
=
$USER
->
id
;
...
...
@@ -5436,9 +5449,6 @@ function forum_print_latest_discussions($course, $forum, $maxdiscussions = -1, $
}
// Use discussion name instead of subject of first post.
$discussion
->
subject
=
$discussion
->
name
;
if
(
FORUM_DISCUSSION_PINNED
==
$discussion
->
pinned
)
{
$discussion
->
subject
=
get_string
(
'discussionpinned'
,
'forum'
,
$discussion
->
subject
);
}
switch
(
$displayformat
)
{
case
'header'
:
...
...
@@ -7776,6 +7786,54 @@ function forum_discussion_view($modcontext, $forum, $discussion) {
$event
->
trigger
();
}
/**
* Set the discussion to pinned and trigger the discussion pinned event
*
* @param stdClass $modcontext module context object
* @param stdClass $forum forum object
* @param stdClass $discussion discussion object
* @since Moodle 3.1
*/
function
forum_discussion_pin
(
$modcontext
,
$forum
,
$discussion
)
{
global
$DB
;
$DB
->
set_field
(
'forum_discussions'
,
'pinned'
,
FORUM_DISCUSSION_PINNED
,
array
(
'id'
=>
$discussion
->
id
));
$params
=
array
(
'context'
=>
$modcontext
,
'objectid'
=>
$discussion
->
id
,
'other'
=>
array
(
'forumid'
=>
$forum
->
id
)
);
$event
=
\
mod_forum\event\discussion_pinned
::
create
(
$params
);
$event
->
add_record_snapshot
(
'forum_discussions'
,
$discussion
);
$event
->
trigger
();
}
/**
* Set discussion to unpinned and trigger the discussion unpin event
*
* @param stdClass $modcontext module context object
* @param stdClass $forum forum object
* @param stdClass $discussion discussion object
* @since Moodle 3.1
*/
function
forum_discussion_unpin
(
$modcontext
,
$forum
,
$discussion
)
{
global
$DB
;
$DB
->
set_field
(
'forum_discussions'
,
'pinned'
,
FORUM_DISCUSSION_UNPINNED
,
array
(
'id'
=>
$discussion
->
id
));
$params
=
array
(