View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001485 | Composr | cns_forum | public | 2014-01-02 19:23 | 2014-12-14 00:09 |
| Reporter | Chris Graham | Assigned To | Chris Graham | ||
| Severity | Feature-request | ||||
| Status | resolved | Resolution | fixed | ||
| Product Version | |||||
| Fixed in Version | |||||
| Summary | 0001485: Post editing time limit | ||||
| Description | Add a new forum option, "minutes before post editing locked". Allow it to be left blank. Add a new privilege, "may edit posts after the time limit". | ||||
| Tags | No tags attached. | ||||
| Time estimation (hours) | 1 | ||||
| Sponsorship open | |||||
|
|
Thank you for the sponsorship OneRingRules. This has now been implemented. Salman will supply the change in one of his updates. |
|
|
Ah, I forgot to mention -- we'll have the same feature for deleting too, separate timer, separate privilege. |
|
|
Tuned this a bit more. Rather than working as a flat "deny, don't offer action", it is a bit smarter. As there is a specific reason why this is denied, I've coded the API to feed through this reason. The edit/delete buttons are set to show if there's a specific reason, and upon clicking them you are told that reason. |
|
|
post-edit-times.diff (14,373 bytes)
diff --git a/data_custom/execute_temp.php b/data_custom/execute_temp.php
index ca71f91..dacdca1 100644
--- a/data_custom/execute_temp.php
+++ b/data_custom/execute_temp.php
@@ -55,4 +55,8 @@ if (!headers_sent())
*/
function execute_temp()
{
+ add_config_option('EDIT_TIME_LIMIT','edit_time_limit','integer','return \'15\';','SECTION_FORUMS','GENERAL');
+ add_specific_permission('SECTION_FORUMS','exceed_post_edit_time_limit',false);
+ add_config_option('DELETE_TIME_LIMIT','delete_time_limit','integer','return \'15\';','SECTION_FORUMS','GENERAL');
+ add_specific_permission('SECTION_FORUMS','exceed_post_delete_time_limit',false);
}
diff --git a/forum/pages/modules/topics.php b/forum/pages/modules/topics.php
index f5623bf..90d1b7c 100644
--- a/forum/pages/modules/topics.php
+++ b/forum/pages/modules/topics.php
@@ -2251,6 +2251,18 @@ END;
if (is_null($topic_id)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$topic_id),'',1);
if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
+
+ $reason=NULL;
+ $may_delete=ocf_may_delete_post_by($post_id,NULL,NULL,NULL,get_member(),$reason);
+ if (!$may_delete)
+ {
+ if (!is_null($reason))
+ {
+ warn_exit($reason);
+ }
+ access_denied('I_ERROR');
+ }
+
$this->handle_topic_breadcrumbs($topic_info[0]['t_forum_id'],$topic_id,$topic_info[0]['t_cache_first_title'],do_lang_tempcode('DELETE_POST'));
if (has_specific_permission(get_member(),'mass_delete_from_ip'))
@@ -2589,8 +2601,16 @@ END;
if (!array_key_exists(0,$post_details)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
$forum_id=$post_details[0]['p_cache_forum_id'];
- if (!ocf_may_edit_post_by($post_details[0]['p_poster'],$forum_id))
+ $reason=NULL;
+ $may_edit=ocf_may_edit_post_by($post_id,$post_details[0]['p_time'],$post_details[0]['p_poster'],$forum_id,get_member(),$reason);
+ if (!$may_edit)
+ {
+ if (!is_null($reason))
+ {
+ warn_exit($reason);
+ }
access_denied('I_ERROR');
+ }
$topic_info=$GLOBALS['FORUM_DB']->query_select('f_topics',array('*'),array('id'=>$post_details[0]['p_topic_id']),'',1);
if (!array_key_exists(0,$topic_info)) warn_exit(do_lang_tempcode('MISSING_RESOURCE'));
@@ -2659,7 +2679,7 @@ END;
$options[]=array(do_lang_tempcode('MARK_UNREAD'),'mark_as_unread',false,do_lang_tempcode('DESCRIPTION_MARK_UNREAD'));
$options[]=array(do_lang_tempcode('SHOW_AS_EDITED'),'show_as_edited',((time()-$post_details[0]['p_time'])>60*3),do_lang_tempcode('DESCRIPTION_POST_SHOW_AS_EDITED'));
$specialisation2->attach(form_input_various_ticks($options,''));
- if (ocf_may_delete_post_by($post_details[0]['p_poster'],$forum_id))
+ if (ocf_may_delete_post_by($post_id,$post_details[0]['p_time'],$post_details[0]['p_poster'],$forum_id))
{
$specialisation2->attach(form_input_tick(do_lang_tempcode('DELETE'),do_lang_tempcode('DESCRIPTION_DELETE'),'delete',false));
}
diff --git a/forum/pages/modules/topicview.php b/forum/pages/modules/topicview.php
index c28a5e4..6dcffa4 100644
--- a/forum/pages/modules/topicview.php
+++ b/forum/pages/modules/topicview.php
@@ -420,7 +420,7 @@ class Module_topicview
unset($topic_info['may_use_quick_reply']);
}
}
- elseif (((is_null($topic_info['forum_id'])) || (has_specific_permission(get_member(),'submit_lowrange_content','topics',array('forums',$topic_info['forum_id'])))) && ($topic_info['last_poster']==get_member()) && (!is_guest()) && (ocf_may_edit_post_by(get_member(),$topic_info['forum_id'])))
+ elseif (((is_null($topic_info['forum_id'])) || (has_specific_permission(get_member(),'submit_lowrange_content','topics',array('forums',$topic_info['forum_id'])))) && ($topic_info['last_poster']==get_member()) && (!is_guest()) && (ocf_may_edit_post_by($topic_info['last_post_id'],$topic_info['last_time'],get_member(),$topic_info['forum_id'])))
{
$map=array('page'=>'topics','type'=>'edit_post','id'=>$topic_info['last_post_id']);
$test=get_param_integer('kfs'.strval($topic_info['forum_id']),-1);
diff --git a/lang/EN/ocf.ini b/lang/EN/ocf.ini
index e766d29..cb1a688 100755
--- a/lang/EN/ocf.ini
+++ b/lang/EN/ocf.ini
@@ -972,3 +972,4 @@ MEMBER_ADDED_TO_GROUP=Member added to usergroup
MEMBER_REMOVED_FROM_GROUP=Member removed from usergroup
MEMBER_PRIMARY_GROUP_CHANGED=Member primary usergroup changed
LIFETIME_POINTS=Life-time point earnings; {1} {1|point|points} available to spend
+EXCEEDED_TIME_LIMIT=You can only perform this action within {1} of making the post.
diff --git a/lang/EN/ocf_config.ini b/lang/EN/ocf_config.ini
index 1a3402d..139e5f8 100644
--- a/lang/EN/ocf_config.ini
+++ b/lang/EN/ocf_config.ini
@@ -155,6 +155,12 @@ PT_multi_delete_topics=Can multi-delete topics
PT_show_user_browsing=See where users currently are on the website, and their choice of web browser
PT_see_hidden_groups=See hidden usergroups and their membership
PT_pt_anyone=Whisper to anyone, regardless of their acceptance settings
+EDIT_TIME_LIMIT=Edit time limit
+CONFIG_OPTION_edit_time_limit=The number of minutes before post editing becomes locked (assuming the “May edit posts after the time limit” privilege has not been granted).
+PT_exceed_post_edit_time_limit=May edit posts after the time limit
+DELETE_TIME_LIMIT=Delete time limit
+CONFIG_OPTION_delete_time_limit=The number of minutes before post deleting becomes locked (assuming the “May delete posts after the time limit” privilege has not been granted).
+PT_exceed_post_delete_time_limit=May delete posts after the time limit
SIGNUP_FULLNAME=Sign-up with full-name
CONFIG_OPTION_signup_fullname=Members sign-up with their full-name, and are then assigned a username automatically based on this. If someone else is already registered with the name, a numbering suffix is added.
INTRO_FORUM_ID=Intro forum ID
diff --git a/sources/ocf_posts.php b/sources/ocf_posts.php
index a5445a3..12e4f3b 100644
--- a/sources/ocf_posts.php
+++ b/sources/ocf_posts.php
@@ -56,59 +56,134 @@ function ocf_may_post_in_topic($forum_id,$topic_id,$last_member_id=NULL,$member_
/**
* Find whether a member may edit the detailed post.
*
- * @param MEMBER The owner of the post.
- * @param ?AUTO_LINK The forum the post is in (NULL: is a Private Topic).
+ * @param AUTO_LINK The post ID.
+ * @param ?TIME The time of the post (NULL: lookup).
+ * @param ?MEMBER The owner of the post (NULL: lookup).
+ * @param ?AUTO_LINK The forum the post is in (NULL: is a Private Topic, unless $post_time is NULL in which case we look this up too).
* @param ?MEMBER The member (NULL: current member).
+ * @param ?tempcode Save the reason into here (NULL: do not save; NULL final value means just generic access denied).
* @return boolean The answer.
*/
-function ocf_may_edit_post_by($resource_owner,$forum_id,$member_id=NULL)
+function ocf_may_edit_post_by($post_id,$post_time=NULL,$resource_owner=NULL,$forum_id=NULL,$member_id=NULL,&$reason=NULL)
{
if (is_null($member_id)) $member_id=get_member();
+ $reason=NULL;
+
+ if (is_null($post_time))
+ {
+ $posts=$GLOBALS['FORUM_DB']->query_select('f_posts',array('p_time','p_poster','p_cache_forum_id'),array('id'=>$post_id),'',1);
+ if (!array_key_exists(0,$posts))
+ {
+ $reason=do_lang_tempcode('INTERNAL_ERROR');
+ return false;
+ }
+ $post_time=$posts[0]['p_time'];
+ $resource_owner=$posts[0]['p_poster'];
+ $forum_id=$posts[0]['p_cache_forum_id'];
+ // TODO v10: $topic_is_closed
+ }
+
+ if (((time()-$post_time)>intval(get_option('edit_time_limit'))*60) && (!has_specific_permission($member_id,'exceed_edit_time_limit')))
+ {
+ $reason=do_lang_tempcode('EXCEEDED_TIME_LIMIT',escape_html(display_time_period(intval(get_option('edit_time_limit'))*60)));
+ return false;
+ }
+
if (is_null($forum_id))
{
- if (has_specific_permission($member_id,'moderate_personal_topic')) return true;
- if (($resource_owner!=$member_id) || (!has_specific_permission($member_id,'delete_personal_topic_posts'))) return false;
+ if (has_specific_permission($member_id,'moderate_personal_topic'))
+ {
+ return true;
+ }
+ if (($resource_owner!=$member_id) || (!has_specific_permission($member_id,'edit_personal_topic_posts')))
+ {
+ return false;
+ }
} else
{
$ticket_forum=get_option('ticket_forum_name',true);
$comments_forum=get_option('comments_forum_name',true);
if ((is_null($ticket_forum)) || (($forum_id!=$GLOBALS['FORUM_DRIVER']->forum_id_from_name($ticket_forum)) && ($forum_id!=$GLOBALS['FORUM_DRIVER']->forum_id_from_name($comments_forum))))
{
- if (!has_category_access($member_id,'forums',strval($forum_id))) return false;
+ if (!has_category_access($member_id,'forums',strval($forum_id)))
+ {
+ return false;
+ }
}
}
- return has_edit_permission('low',$member_id,$resource_owner,'topics',array('forums',$forum_id));
+ if (!has_edit_permission('low',$member_id,$resource_owner,'topics',array('forums',$forum_id)))
+ {
+ return false;
+ }
+ return true;
}
/**
* Find whether a member may delete the detailed post.
*
- * @param MEMBER The owner of the post.
- * @param ?AUTO_LINK The forum the post is in (NULL: is a Private Topic).
+ * @param AUTO_LINK The post ID.
+ * @param ?TIME The time of the post (NULL: lookup).
+ * @param ?MEMBER The owner of the post (NULL: lookup).
+ * @param ?AUTO_LINK The forum the post is in (NULL: is a Private Topic, unless $post_time is NULL in which case we look this up too).
* @param ?MEMBER The member (NULL: current member).
+ * @param ?tempcode Save the reason into here (NULL: do not save; NULL final value means just generic access denied).
* @return boolean The answer.
*/
-function ocf_may_delete_post_by($resource_owner,$forum_id,$member_id=NULL)
+function ocf_may_delete_post_by($post_id,$post_time=NULL,$resource_owner=NULL,$forum_id=NULL,$member_id=NULL,&$reason=NULL)
{
if (is_null($member_id)) $member_id=get_member();
+ $reason=NULL;
+
+ if (is_null($post_time))
+ {
+ $posts=$GLOBALS['FORUM_DB']->query_select('f_posts',array('p_time','p_poster','p_cache_forum_id'),array('id'=>$post_id),'',1);
+ if (!array_key_exists(0,$posts))
+ {
+ return false;
+ }
+ $post_time=$posts[0]['p_time'];
+ $resource_owner=$posts[0]['p_poster'];
+ $forum_id=$posts[0]['p_cache_forum_id'];
+ // TODO v10: $topic_is_closed
+ }
+
+ if (((time()-$post_time)>intval(get_option('delete_time_limit'))*60) && (!has_specific_permission($member_id,'exceed_delete_time_limit')))
+ {
+ $reason=do_lang_tempcode('EXCEEDED_TIME_LIMIT',escape_html(display_time_period(intval(get_option('delete_time_limit'))*60)));
+ return false;
+ }
+
if (is_null($forum_id))
{
- if (has_specific_permission($member_id,'moderate_personal_topic')) return true;
- if (($resource_owner!=$member_id) || (!has_specific_permission($member_id,'delete_personal_topic_posts'))) return false;
+ if (has_specific_permission($member_id,'moderate_personal_topic'))
+ {
+ return true;
+ }
+ if (($resource_owner!=$member_id) || (!has_specific_permission($member_id,'delete_personal_topic_posts')))
+ {
+ return false;
+ }
} else
{
$ticket_forum=get_option('ticket_forum_name',true);
$comments_forum=get_option('comments_forum_name',true);
if ((is_null($ticket_forum)) || (($forum_id!=$GLOBALS['FORUM_DRIVER']->forum_id_from_name($ticket_forum)) && ($forum_id!=$GLOBALS['FORUM_DRIVER']->forum_id_from_name($comments_forum))))
{
- if (!has_category_access($member_id,'forums',strval($forum_id))) return false;
+ if (!has_category_access($member_id,'forums',strval($forum_id)))
+ {
+ return false;
+ }
}
}
- return has_delete_permission('low',$member_id,$resource_owner,'topics',array('forums',$forum_id));
+ if (!has_delete_permission('low',$member_id,$resource_owner,'topics',array('forums',$forum_id)))
+ {
+ return false;
+ }
+ return true;
}
/**
diff --git a/sources/ocf_posts_action3.php b/sources/ocf_posts_action3.php
index 46b552b..ee49e9a 100644
--- a/sources/ocf_posts_action3.php
+++ b/sources/ocf_posts_action3.php
@@ -115,7 +115,7 @@ function ocf_edit_post($post_id,$validated,$title,$post,$skip_sig,$is_emphasised
ocf_check_post($post);
if ($check_perms)
- if (!ocf_may_edit_post_by($post_owner,$forum_id)) access_denied('I_ERROR');
+ if (!ocf_may_edit_post_by($post_id,$post_info[0]['p_time'],$post_owner,$forum_id)) access_denied('I_ERROR');
if ((is_null($validated)) || ($validated==1))
{
if ((!is_null($forum_id)) && (!has_specific_permission(get_member(),'bypass_validation_lowrange_content','topics',array('forums',$forum_id)))) $validated=0; else $validated=1;
@@ -226,7 +226,7 @@ function ocf_delete_posts_topic($topic_id,$posts,$reason)
{
if ((is_null($post['p_intended_solely_for'])) && ($post['p_validated']==1)) $num_posts_counted++;
$post_owner=$post['p_poster'];
- if (!ocf_may_delete_post_by($post_owner,$forum_id)) access_denied('I_ERROR');
+ if (!ocf_may_delete_post_by($post['id'],$post['p_time'],$post_owner,$forum_id)) access_denied('I_ERROR');
}
// Save in history
diff --git a/sources/ocf_topicview.php b/sources/ocf_topicview.php
index 86fea7a..01f57cf 100755
--- a/sources/ocf_topicview.php
+++ b/sources/ocf_topicview.php
@@ -207,8 +207,20 @@ function ocf_get_details_to_show_post($_postdetails,$only_post=false)
// Do we have any special controls over this post?
require_code('ocf_posts');
- if (ocf_may_edit_post_by($_postdetails['p_poster'],$forum_id)) $post['may_edit']=true;
- if ((ocf_may_delete_post_by($_postdetails['p_poster'],$forum_id)) && (!$only_post)) $post['may_delete']=true;
+ $reason=NULL;
+ $may_edit=ocf_may_edit_post_by($_postdetails['id'],$_postdetails['p_time'],$_postdetails['p_poster'],$forum_id,get_member(),$reason);
+ if ($may_edit || $reason!==NULL/*Interesting reason, let them find it out when they click*/)
+ {
+ $post['may_edit']=true;
+ }
+ if (!$only_post)
+ {
+ $may_delete=ocf_may_delete_post_by($_postdetails['id'],$_postdetails['p_time'],$_postdetails['p_poster'],$forum_id,get_member(),$reason);
+ if ($may_delete || $reason!==NULL/*Interesting reason, let them find it out when they click*/)
+ {
+ $post['may_delete']=true;
+ }
+ }
// More
if (has_specific_permission(get_member(),'see_ip')) $post['ip_address']=$_postdetails['p_ip_address'];
|