--- a/taskbuilder/includes/admin/projects/open_project/wppm_submit_project_comment.php
+++ b/taskbuilder/includes/admin/projects/open_project/wppm_submit_project_comment.php
@@ -7,10 +7,17 @@
wp_send_json_error( 'Unauthorised request!', 401 );
}
$proj_id = isset($_POST['proj_id']) ? intval(sanitize_text_field($_POST['proj_id'])) : '' ;
+if(!$wppmfunction->has_project_permission('add_proj_comment',$proj_id)){
+ wp_send_json_error( 'Unauthorised request!', 403 );
+}
$cu_id = $current_user->ID;
+$project_data = $wppmfunction->get_project($proj_id);
+if (empty($project_data)) {
+ wp_send_json_error( 'Project not found', 404 );
+}
$comment = isset($_POST['comment_body']) ? ($_POST['comment_body']) : '' ;
$allowed_tags = array( 'br' => array(), 'abbr' => array('title' => array(),), 'p' => array(), 'strong' => array(), 'a' => array('href' => array(), 'title' => array(), 'rel'=> array(), 'target'=> array()),'em' =>array(),'span' =>array(), 'blockquote'=>array('cite' => array(),),'div' => array('class' => array(),'title' => array(),'style' => array(),),'ul'=>array(),'li'=>array(),'ol'=>array(),'img' => array( 'alt'=> array(),'class' => array(),'height' => array(),'src'=> array(),'width'=> array(),));
-$comment_body = wp_kses(htmlspecialchars_decode($comment, ENT_QUOTES),$allowed_tags);
+$comment_body = wp_kses($comment,$allowed_tags);
$attachments = !empty($_POST['wppm_proj_comment_attachment']) ? $wppmfunction->sanitize_array($_POST['wppm_proj_comment_attachment']) : [];
$attachment_ids = implode(",",$attachments);
if($comment_body=="" && $attachment_ids=="") exit;
--- a/taskbuilder/includes/admin/projects/open_project/wppm_view_project_tasks.php
+++ b/taskbuilder/includes/admin/projects/open_project/wppm_view_project_tasks.php
@@ -21,6 +21,7 @@
$wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
$wppm_hide_completed_status_task = get_option('wppm_hide_completed_status_task');
$wppm_hide_task_statuses_from_frontend = get_option('wppm_hide_task_statuses_from_frontend');
+$wppm_deafault_time_duration_task = get_option('wppm_display_time_duration_task');
if(!empty($wppm_hide_task_statuses_from_frontend)){
$wppm_hide_task_statuses_from_frontend = explode(",",$wppm_hide_task_statuses_from_frontend);
} else {
@@ -345,6 +346,7 @@
foreach($wppm_task_fillter as $key=>$tasks){
foreach($tasks as $task){
$total_tasks++;
+ $wppm_task_duration = $wppmfunction->wppm_get_duration($task->start_date,$task->end_date);
if((!empty($task)) && $task->status==$status->id){
$task_per_status = true;
if(isset($task->priority)){
@@ -426,10 +428,17 @@
</div>
</div>
<div>
- <div class="wppm_task_due_date_grid_view" style="margin-left: 5px;">
- <?php $style = ($task->status!=4 && $task->end_date < $current_date) ? "color:#FF0000":"color:#2C3E50"; ?>
- <small style="<?php echo esc_attr($style); ?>"><?php echo (isset($task_end_date))? esc_html_e($task_end_date,'taskbuilder') :"" ?></small>
- </div>
+ <?php if($wppm_deafault_time_duration_task==0) { ?>
+ <div class="wppm_task_due_date_grid_view" style="margin-left: 5px;">
+ <?php $style = ($task->status!=4 && $task->end_date < $current_date) ? "color:#FF0000":"color:#2C3E50"; ?>
+ <small style="<?php echo esc_attr($style); ?>"><?php echo (isset($task_end_date))? esc_html_e($task_end_date,'taskbuilder') :"" ?></small>
+ </div>
+ <?php }elseif( $wppm_deafault_time_duration_task==1){ ?>
+ <div class="wppm_task_due_date_grid_view" style="margin-left: 5px;">
+ <?php $style = ($task->status!=4 && $task->end_date < $current_date) ? "color:#FF0000":"color:#2C3E50"; ?>
+ <small style="<?php echo esc_attr($style); ?>"><?php echo (isset($wppm_task_duration))? esc_html_e($wppm_task_duration,'taskbuilder') :"" ?></small>
+ </div>
+ <?php } ?>
<div class="wppm_card_task_users" style="text-align:right;">
<?php
$task_users = explode(',',$task->users);
--- a/taskbuilder/includes/admin/projects/projects_list.php
+++ b/taskbuilder/includes/admin/projects/projects_list.php
@@ -7,6 +7,7 @@
$categories = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_project_categories" );
$appearance_settings = get_option("wppm-ap-project-list");
$wppm_date_setting = get_option('wppm_date_setting');
+$wppm_deafault_time_duration_project = get_option('wppm_display_time_duration_project');
$wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
$proj_per_page = 20;
$page_no = (isset($_POST['page_no'])) ? intval(sanitize_text_field($_POST['page_no'])): '0';
@@ -51,21 +52,24 @@
'filter'=>$filter_by
);
setcookie('wppm_proj_filters',wp_json_encode( $filters ),time() + 3600);
-if($pl_filters_arr['sort_by']=='status'){
- $sort_by = 'proj_statuses.name';
-}
-if($pl_filters_arr['sort_by']=='category'){
- $sort_by = 'proj_categories.name';
-}
-if($pl_filters_arr['sort_by']=='start_date'){
- $sort_by = 'start_date';
-}
-if($pl_filters_arr['sort_by']=='end_date'){
- $sort_by = 'end_date';
-}
-if($sort_by=='category'){
- $sort_by = 'proj_categories.name';
-}
+
+$allowed_sort_by = [
+ 'project_name' => 'project_name',
+ 'status' => 'proj_statuses.name',
+ 'category' => 'proj_categories.name',
+ 'start_date' => 'start_date',
+ 'end_date' => 'end_date',
+ 'TIMESTAMPDIFF(SECOND, start_date, end_date)'=> 'TIMESTAMPDIFF(SECOND, start_date, end_date)'
+];
+// Resolve sort_by safely
+$sort_key = isset($pl_filters_arr['sort_by'])
+ ? sanitize_text_field($pl_filters_arr['sort_by'])
+ : 'project_name';
+
+$sort_by = $allowed_sort_by[$sort_key] ?? 'project_name';
+$order = ( isset($pl_filters_arr['order']) && strtoupper($pl_filters_arr['order']) === 'ASC' )
+ ? 'ASC'
+ : 'DESC';
if($filter_by=='all'){
if($wppm_hide_completed_status_proj == 0){
$wppm_pl_filter = "status!='4'";
@@ -133,8 +137,6 @@
$no_of_rows = ( "SELECT count(*) FROM ($query");
$no_of_rows = apply_filters('wppm_project_list_no_of_rows',$no_of_rows,$wppm_pl_filter,$search_tag);
$where = apply_filters('wppm_project_list_query_where',$where, $wppm_pl_filter,$search_tag);
-$sort_by = esc_sql($sort_by);
-$order = esc_sql($order);
$query .= $where." Group by Project.id ORDER BY $sort_by $order";
$no_of_rows .= $where." Group by Project.id) AS Project";
$totalrows = $wpdb->get_var( $no_of_rows );
@@ -246,7 +248,7 @@
<img width="16" height="16" onclick="wppm_sort_up_project_list('category','ASC')" style = "<?php echo ($sort_by == 'proj_categories.name' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" class="wppm_chevron_img" id="wppm_chevron_sort_up_project_cat_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
<img width="16" height="16" onclick="wppm_sort_up_project_list('category','DESC')" style = "<?php echo ($sort_by == 'proj_categories.name' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" class="wppm_chevron_img" id="wppm_chevron_sort_down_project_cat_img" class="wppm_chevron_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
</th>
- <?php if($wppm_default_project_date==1){ ?>
+ <?php if($wppm_default_project_date==1 && $wppm_deafault_time_duration_project==0){ ?>
<th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
<span id="wppm_project_start_date_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Start Date','taskbuilder'); ?></span>
<img width="16" height="16" onclick="wppm_sort_up_project_list('start_date','ASC')" style = "<?php echo ($sort_by == 'start_date' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" class="wppm_chevron_img" id="wppm_chevron_sort_up_project_start_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
@@ -257,7 +259,14 @@
<img width="16" height="16" onclick="wppm_sort_up_project_list('end_date','ASC')" style = "<?php echo ($sort_by == 'end_date' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" class="wppm_chevron_img" id="wppm_chevron_sort_up_project_end_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
<img width="16" height="16" onclick="wppm_sort_up_project_list('end_date','DESC')" style = "<?php echo ($sort_by == 'end_date' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" class="wppm_chevron_img" id="wppm_chevron_sort_down_project_end_date_img" class="wppm_chevron_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
</th>
- <?php } ?>
+ <?php }
+ if( $wppm_deafault_time_duration_project==1){ ?>
+ <th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
+ <span id="wppm_project_time_duration_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Duration','taskbuilder'); ?></span>
+ <img width="16" height="16" onclick="wppm_sort_up_project_list('TIMESTAMPDIFF(SECOND, start_date, end_date)','ASC')" style = "<?php echo ($sort_by == 'TIMESTAMPDIFF(SECOND, start_date, end_date)' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" class="wppm_chevron_img" id="wppm_chevron_sort_up_project_time_duration_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
+ <img width="16" height="16" onclick="wppm_sort_up_project_list('TIMESTAMPDIFF(SECOND, start_date, end_date)','DESC')" style = "<?php echo ($sort_by == 'TIMESTAMPDIFF(SECOND, start_date, end_date)' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" class="wppm_chevron_img" id="wppm_chevron_sort_down_project_time_duration_img" class="wppm_chevron_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
+ </th>
+ <?php }?>
<th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>"><span style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('No. of tasks','taskbuilder'); ?></span></th>
<th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>"></th>
</tr>
@@ -269,6 +278,7 @@
foreach( $wppm_fillter as $project ){
$total_projects++;
$proejctdata = $wppmfunction->get_project($project->id);
+ $wppm_proj_duration = $wppmfunction->wppm_get_duration($project->start_date,$project->end_date);
$pstatus= esc_sql($project->status);
$status = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_project_statuses where id='$pstatus'" );
$users = explode(",",$project->users);
@@ -419,8 +429,7 @@
<?php } ?>
</td>
<td onmouseover="link=true;" class="wppm_table_td"><?php echo isset($category) ? esc_html_e($category,'taskbuilder'): "" ?></td>
- <?php if($wppm_default_project_date==1){
- ?>
+ <?php if($wppm_default_project_date==1 && $wppm_deafault_time_duration_project==0){ ?>
<td onmouseover="link=true;" class="wppm_table_td"><?php echo isset($proj_start_date) ? esc_html($proj_start_date): "" ?></td>
<?php
if(!empty($proj_end_date) && $project->status!=4 && $proj_end_date < $current_date && ($proj_end_date != '0000-00-00 00:00:00' && $proj_end_date != '00-00-0000 00:00:00' && $proj_end_date != '00-00-0000' && $proj_end_date != '0000-00-00')) {
@@ -430,6 +439,15 @@
} ?>
<td onmouseover="link=true;" class="wppm_table_td"><span style="<?php echo esc_attr($style); ?>"><?php echo isset($proj_end_date) ? esc_html($proj_end_date):"" ?></span></td>
<?php } ?>
+ <?php if($wppm_deafault_time_duration_project==1){ ?>
+ <?php
+ if(!empty($proj_end_date) && $project->status!=4 && $proj_end_date < $current_date && ($proj_end_date != '0000-00-00 00:00:00' && $proj_end_date != '00-00-0000 00:00:00' && $proj_end_date != '00-00-0000' && $proj_end_date != '0000-00-00')) {
+ $style = "color:#FF0000";
+ } else {
+ $style = "color:#2C3E50";
+ } ?>
+ <td onmouseover="link=true;" class="wppm_table_td"><span style="<?php echo esc_attr($style); ?>"><?php echo isset($wppm_proj_duration) ? esc_html($wppm_proj_duration):"" ?></span></td>
+ <?php } ?>
<td onmouseover="link=true;" class="wppm_table_td"><?php echo isset($no_of_tasks) ? esc_html($no_of_tasks):"" ?></td>
<td onmouseover="link=true;" class="wppm_delete_action">
<?php $style = (($current_user->ID && $current_user->has_cap('manage_options')) || ($wppmfunction->has_project_permission('delete_project',esc_attr($project->id))) || $wppm_current_user_capability == 'wppm_admin' || ($proejctdata['created_by']==$current_user->ID && $wppm_current_user_capability == 'wppm_manager') )? "display:inline":"display:none"; ?>
@@ -523,6 +541,10 @@
jQuery('#wppm_chevron_sort_up_project_end_date_img').show();
jQuery('#wppm_chevron_sort_down_project_end_date_img').hide();
});
+ jQuery("#wppm_project_time_duration_th").hover(function(){
+ jQuery('#wppm_chevron_sort_up_project_time_duration_img').show();
+ jQuery('#wppm_chevron_sort_down_project_time_duration_img').hide();
+ });
jQuery(".wppm_delete_action").on("click", function(e){
e.preventDefault();
return false;
--- a/taskbuilder/includes/admin/projects/wppm_open_project.php
+++ b/taskbuilder/includes/admin/projects/wppm_open_project.php
@@ -14,6 +14,7 @@
$wppm_date_setting = get_option('wppm_date_setting');
$wppm_proj_hide_comment_section = get_option('wppm_proj_hide_comment_section');
$wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
+$wppm_deafault_time_duration_project = get_option('wppm_display_time_duration_project');
$current_date = date('Y-m-d');
$id = isset($_POST) && isset($_POST['id']) ? intval(sanitize_text_field($_POST['id'])) : 0;
if (!isset($id)) {exit;}
@@ -198,7 +199,7 @@
<span class="wppm_project_details"><?php echo isset($proj_create_date) ? esc_html($proj_create_date):"" ?></span>
</div>
</div>
- <?php if($wppm_default_project_date==1) { ?>
+ <?php if($wppm_default_project_date==1 && $wppm_deafault_time_duration_project==0) { ?>
<div class="row">
<div class="col-sm-3">
<span class="wppm_project_details_label"><?php echo esc_html_e('Start Date:','taskbuilder');?></span>
@@ -220,7 +221,19 @@
</div>
<input type="hidden" name="wppm_edit_pend_date_ajax_nonce" id="wppm_edit_pend_date_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_set_change_proj_end_date' ) ); ?>">
</div>
- <?php } ?>
+ <?php } if($wppm_deafault_time_duration_project==1){
+ $wppm_proj_duration = $wppmfunction->wppm_get_duration($project->start_date,$project->end_date);
+ $pstatus = isset($project->status) ? $project->status :"";
+ $style = (!empty($proj_end_date) && $pstatus!=4 && $proj_end_date < $current_date && ($proj_end_date != '0000-00-00 00:00:00' && $proj_end_date != '00-00-0000 00:00:00' && $proj_end_date != '00-00-0000' && $proj_end_date != '0000-00-00')) ? "color:#FF0000":"color:#2C3E50"; ?>
+ <div class="row">
+ <div class="col-sm-3">
+ <span class="wppm_project_details_label"><?php echo esc_html_e('Project Duration:','taskbuilder');?></span>
+ </div>
+ <div class="col-sm-9">
+ <span class="wppm_project_details" id="wppm_edit_proj_duration" style="<?php echo esc_attr($style); ?>"><?php echo (isset($wppm_proj_duration))? esc_html($wppm_proj_duration): "" ?></span>
+ </div>
+ </div> <?php
+ }?>
<div class="row">
<div class="col-sm-3">
<span class="wppm_project_details_label"><?php echo esc_html_e('Project Category:','taskbuilder');?></span>
--- a/taskbuilder/includes/admin/settings/wppm_get_general_settings.php
+++ b/taskbuilder/includes/admin/settings/wppm_get_general_settings.php
@@ -25,6 +25,8 @@
$wppm_hide_completed_status_task = get_option('wppm_hide_completed_status_task');
$wppm_proj_hide_comment_section = get_option('wppm_proj_hide_comment_section');
$wppm_task_hide_comment_section = get_option('wppm_task_hide_comment_section');
+$wppm_deafault_time_duration_project = get_option('wppm_display_time_duration_project');
+$wppm_deafault_time_duration_task = get_option('wppm_display_time_duration_task');
?>
<form id="wppm_frm_general_settings" method="post" action="javascript:wppm_set_general_settings();">
<div class="wppm-help-container">
@@ -41,6 +43,26 @@
<span style="padding-left: 10px;"><?php echo esc_html_e('Card View','taskbuilder');?></span>
<hr>
<span>
+ <label><?php echo esc_html_e('Show project duration instead of start and end dates in the project list.','taskbuilder');?></label>
+ </span><br>
+ <p class="help-block"><?php echo esc_html_e('Default show/hide time duration of project.','taskbuilder');?></p>
+ <input type="radio" name="wppm_display_time_duration_project" style="margin-top: 0px;" value="1" <?php echo ((esc_attr($wppm_deafault_time_duration_project))==1) ?'checked="checked"':'';?>>
+ <span style="padding-left: 10px;"><?php echo esc_html_e('Show','taskbuilder');?></span>
+ <br>
+ <input type="radio" name="wppm_display_time_duration_project" value="0" <?php echo ((esc_attr($wppm_deafault_time_duration_project))==0)?'checked="checked"':'';?>>
+ <span style="padding-left: 10px;"><?php echo esc_html_e('Hide','taskbuilder');?></span>
+ <hr>
+ <span>
+ <label><?php echo esc_html_e('Show task duration instead of start and end dates in the task list.','taskbuilder');?></label>
+ </span><br>
+ <p class="help-block"><?php echo esc_html_e('Default show/hide time duration of task.','taskbuilder');?></p>
+ <input type="radio" name="wppm_display_time_duration_task" style="margin-top: 0px;" value="1" <?php echo ((esc_attr($wppm_deafault_time_duration_task))==1) ?'checked="checked"':'';?>>
+ <span style="padding-left: 10px;"><?php echo esc_html_e('Show','taskbuilder');?></span>
+ <br>
+ <input type="radio" name="wppm_display_time_duration_task" value="0" <?php echo ((esc_attr($wppm_deafault_time_duration_task))==0)?'checked="checked"':'';?>>
+ <span style="padding-left: 10px;"><?php echo esc_html_e('Hide','taskbuilder');?></span>
+ <hr>
+ <span>
<label><?php echo esc_html_e('Time in project start date and end date','taskbuilder');?></label>
</span><br>
<p class="help-block"><?php echo esc_html_e('Default show/hide time in start and end date of project.','taskbuilder');?></p>
--- a/taskbuilder/includes/admin/settings/wppm_set_general_settings.php
+++ b/taskbuilder/includes/admin/settings/wppm_set_general_settings.php
@@ -12,6 +12,10 @@
}
$wppm_task_list_view = isset($_POST) && isset(($_POST['wppm_task_list_view'])) ? sanitize_text_field($_POST['wppm_task_list_view']) : '';
update_option('wppm_default_task_list_view',$wppm_task_list_view);
+$wppm_display_time_duration_project = isset($_POST) && isset(($_POST['wppm_display_time_duration_project'])) ? sanitize_text_field($_POST['wppm_display_time_duration_project']) : '0';
+update_option('wppm_display_time_duration_project',$wppm_display_time_duration_project);
+$wppm_display_time_duration_task = isset($_POST) && isset(($_POST['wppm_display_time_duration_task'])) ? sanitize_text_field($_POST['wppm_display_time_duration_task']) : '0';
+update_option('wppm_display_time_duration_task',$wppm_display_time_duration_task);
$wppm_project_time = isset($_POST) && isset(($_POST['wppm_project_time'])) ? sanitize_text_field($_POST['wppm_project_time']) : '1';
update_option('wppm_project_time',$wppm_project_time);
$wppm_default_project_date = isset($_POST) && isset(($_POST['wppm_default_project_date'])) ? sanitize_text_field($_POST['wppm_default_project_date']) : '1';
--- a/taskbuilder/includes/admin/tasks/open_task/wppm_open_task.php
+++ b/taskbuilder/includes/admin/tasks/open_task/wppm_open_task.php
@@ -15,6 +15,7 @@
$wppm_toolbar_actions = get_option('wppm_toolbar_actions');
$wppm_date_setting = get_option('wppm_date_setting');
$wppm_task_hide_comment_section = get_option('wppm_task_hide_comment_section');
+$wppm_deafault_time_duration_task = get_option('wppm_display_time_duration_task');
$url_auth = false;
$auth_id = $wppmfunction->wppm_get_auth_code($id);
$auth_id = sanitize_text_field($auth_id);
@@ -277,7 +278,7 @@
<span class="wppm_task_details"><?php echo (isset($task_create_date))? esc_html($task_create_date):"" ?></span>
</div>
</div>
- <?php if($wppm_default_task_date == 1){ ?>
+ <?php if($wppm_default_task_date == 1 && $wppm_deafault_time_duration_task==0){ ?>
<div class="row">
<div class="col-sm-3">
<span class="wppm_task_details_label"><?php echo esc_html_e('Start Date:','taskbuilder');?></span>
@@ -297,7 +298,20 @@
</div>
<input type="hidden" name="wppm_edit_tend_date_ajax_nonce" id="wppm_edit_tend_date_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_set_change_task_end_date' ) ); ?>">
</div>
- <?php } ?>
+ <?php }
+ if($wppm_deafault_time_duration_task==1){
+ $wppm_task_duration = $wppmfunction->wppm_get_duration($task->start_date,$task->end_date);
+ $tstatus = isset($task->status) ? $task->status :"";
+ $style = (!empty($task->end_date) && $tstatus!=4 && $task->end_date < $current_date && ($task->end_date != '0000-00-00 00:00:00' && $task->end_date != '00-00-0000 00:00:00' && $task->end_date != '00-00-0000' && $task->end_date != '0000-00-00')) ? "color:#FF1111":"color:#2C3E51"; ?>
+ <div class="row">
+ <div class="col-sm-3">
+ <span class="wppm_task_details_label"><?php echo esc_html_e('Task Duration:','taskbuilder');?></span>
+ </div>
+ <div class="col-sm-9">
+ <span class="wppm_task_details" id="wppm_edit_task_duration" style="<?php echo esc_attr($style); ?>"><?php echo (isset($wppm_task_duration))? esc_html($wppm_task_duration): "" ?></span>
+ </div>
+ </div> <?php
+ }?>
<div class="row">
<div class="col-sm-3">
<span class="wppm_task_details_label"><?php echo esc_html_e('Task Priority:','taskbuilder');?></span>
--- a/taskbuilder/includes/admin/tasks/open_task/wppm_submit_task_comment.php
+++ b/taskbuilder/includes/admin/tasks/open_task/wppm_submit_task_comment.php
@@ -7,9 +7,10 @@
wp_send_json_error( 'Unauthorised request!', 401 );
}
$task_id = isset($_POST['task_id']) ? intval(sanitize_text_field($_POST['task_id'])) : '' ;
+if(!$wppmfunction->has_permission('add_task_comment',$task_id)){ exit; }
$comment = isset($_POST['comment_body']) ? ($_POST['comment_body']) : '' ;
$allowed_tags = array( 'br' => array(), 'abbr' => array('title' => array(),), 'p' => array(), 'strong' => array(), 'a' => array('href' => array(), 'title' => array(), 'rel'=> array(), 'target'=> array()),'em' =>array(),'span' =>array(), 'blockquote'=>array('cite' => array(),),'div' => array('class' => array(),'title' => array(),'style' => array(),),'ul'=>array(),'li'=>array(),'ol'=>array(),'img' => array( 'alt'=> array(),'class' => array(),'height' => array(),'src'=> array(),'width'=> array(),));
-$comment_body = wp_kses(htmlspecialchars_decode($comment, ENT_QUOTES),$allowed_tags);
+$comment_body = wp_kses($comment,$allowed_tags);
$attachments = !empty($_POST['wppm_comment_attachment']) ? $wppmfunction->sanitize_array($_POST['wppm_comment_attachment']) : [];
$attachment_ids = implode(",",$attachments);
if($comment_body=="" && $attachment_ids=="") exit;
@@ -28,5 +29,4 @@
$comment_id = $wppmfunction->wppm_submit_task_comment($args);
$task_log_values = array('task_id'=>esc_sql($task_id),'comment_id'=>esc_sql($comment_id),'comment_type'=>'comment');
$wpdb->insert($wpdb->prefix . 'wppm_task_comment_meta',$task_log_values);
-do_action('wppm_after_submit_task_comment', $task_id,$comment_id);
-
+do_action('wppm_after_submit_task_comment', $task_id,$comment_id);
No newline at end of file
--- a/taskbuilder/includes/admin/tasks/wppm_tasks_list.php
+++ b/taskbuilder/includes/admin/tasks/wppm_tasks_list.php
@@ -19,6 +19,7 @@
$wppm_date_setting = get_option('wppm_date_setting');
$wppm_hide_completed_status_task = get_option('wppm_hide_completed_status_task');
$wppm_hide_task_statuses_from_frontend = get_option('wppm_hide_task_statuses_from_frontend');
+$wppm_deafault_time_duration_task = get_option('wppm_display_time_duration_task');
if(!empty($wppm_hide_task_statuses_from_frontend)){
$wppm_hide_task_statuses_from_frontend = explode(",",$wppm_hide_task_statuses_from_frontend);
} else {
@@ -100,21 +101,28 @@
);
setcookie('wppm_filters',wp_json_encode( $filters ),time() + 3600);
-if($tl_filters_arr['sort_by']=='project'){
- $sort_by = 'proj.project_name';
-}
-if($tl_filters_arr['sort_by']=='start_date'){
- $sort_by = 'Task.start_date';
-}
-if($tl_filters_arr['sort_by']=='end_date'){
- $sort_by = 'Task.end_date';
-}
-if($tl_filters_arr['sort_by']=='status'){
- $sort_by = 'task_statuses.name';
-}
-if($tl_filters_arr['sort_by']=='priority'){
- $sort_by='task_priorities.name';
-}
+// Allowed sort columns
+$allowed_sort_by = [
+ 'project' => 'proj.project_name',
+ 'status' => 'task_statuses.name',
+ 'priority' => 'task_priorities.name',
+ 'start_date' => 'Task.start_date',
+ 'end_date' => 'Task.end_date',
+ 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)' => 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)',
+];
+
+// Resolve sort_by safely
+$sort_key = isset($_POST['sort_by'])
+ ? sanitize_text_field($_POST['sort_by'])
+ : ($tl_filters_arr['sort_by'] ?? 'task_name');
+
+$sort_by = $allowed_sort_by[$sort_key] ?? 'task_name';
+
+// Resolve order safely
+$order = (isset($_POST['order']) && strtoupper($_POST['order']) === 'ASC')
+ ? 'ASC'
+ : 'DESC';
+
if($filter_by=='all'){
if($wppm_hide_completed_status_task == 0){
$wppm_tl_filter = "Task.status!='4'";
@@ -227,8 +235,6 @@
$no_of_rows .= $no_of_rows_where;
$no_of_rows = apply_filters('wppm_task_list_no_of_rows',$no_of_rows,$wppm_tl_filter,$search_tag_text);
$totalrows = $wpdb->get_var($no_of_rows);
-$sort_by = esc_sql($sort_by);
-$order = esc_sql($order);
$query .= $where." Group by Task.id ORDER BY ".$sort_by." ".$order."";
$query = apply_filters('wppm_task_list_query',$query);
$limit_start=$page_no*$task_per_page;
@@ -398,7 +404,7 @@
<img width="16" height="16" style = "<?php echo ($sort_by == ('task_priorities.name') && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('priority','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_priority_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
<img width="16" height="16" style = "<?php echo ($sort_by == ('task_priorities.name') && $order == 'ASC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('priority','DESC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_down_priority_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
</th>
- <?php if($wppm_default_task_date == 1) { ?>
+ <?php if($wppm_default_task_date == 1 && $wppm_deafault_time_duration_task==0) { ?>
<th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
<span id="wppm_start_date_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Start date','taskbuilder'); ?></span>
<img width="16" height="16" style = "<?php echo ($sort_by == 'Task.start_date' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('start_date','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_start_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
@@ -409,7 +415,14 @@
<img width="16" height="16" style = "<?php echo ($sort_by == 'Task.end_date' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('end_date','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_end_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
<img width="16" height="16" style = "<?php echo ($sort_by == 'Task.end_date' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('end_date','DESC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_down_end_date_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
</th>
- <?php } ?>
+ <?php }
+ if( $wppm_deafault_time_duration_task==1){ ?>
+ <th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
+ <span id="wppm_task_duration_th" style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Duration','taskbuilder'); ?></span>
+ <img width="16" height="16" style = "<?php echo ($sort_by == 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)' && $order == 'DESC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)','ASC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_up_task_duration_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_up_icon.svg'); ?>" alt="chevron_sort_up_icon">
+ <img width="16" height="16" style = "<?php echo ($sort_by == 'TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)' && $order == 'ASC') ? 'display:inline': 'display:none;'?>" onclick="wppm_sort_up_task_list('TIMESTAMPDIFF(SECOND, Task.start_date, Task.end_date)','DESC','<?php echo esc_attr($page); ?>')" class="wppm_chevron_img" id="wppm_chevron_sort_down_task_duration_img" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/sort_down_icon.svg'); ?>" alt="chevron_sort_down_icon">
+ </th>
+ <?php }?>
<th class="wppm_table_header" style="background-color:<?php echo esc_attr($appearance_settings['list-header-background-color'])?>">
<span style="color:<?php echo esc_attr($appearance_settings['list-header-text-color'])?>"><?php echo esc_html_e('Assign To','taskbuilder'); ?></span>
</th>
@@ -425,6 +438,7 @@
if(!empty($wppm_task_fillter)){
foreach($wppm_task_fillter as $task) {
$task_id = esc_sql($task->id);
+ $wppm_task_duration = $wppmfunction->wppm_get_duration($task->start_date,$task->end_date);
$checklists = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id = '$task_id'" );
if(!empty($task)){
$taskdata = $wppmfunction->get_task($task->id);
@@ -568,7 +582,7 @@
<span class ="wppm_td_task_priority" style="background-color:<?php echo (isset($priority->bg_color))? esc_attr($priority->bg_color):"" ;?>; color: <?php echo (isset($priority->color))? esc_attr($priority->color):""; ?>"><?php echo (isset($priority->name))? esc_html_e($priority->name,'taskbuilder'):"" ?></span>
<?php } ?>
</td>
- <?php if($wppm_default_task_date == 1) { ?>
+ <?php if($wppm_default_task_date == 1 && $wppm_deafault_time_duration_task==0) { ?>
<td onmouseover="link=true;">
<?php if(!empty($task_start_date)){ ?>
<?php echo esc_html_e($task_start_date,'taskbuilder');
@@ -583,6 +597,15 @@
<span style="<?php echo esc_attr($style); ?>"><?php echo esc_html_e($task_end_date,'taskbuilder');?></span>
</td>
<?php } ?>
+ <?php if($wppm_deafault_time_duration_task==1){ ?>
+ <?php
+ if(!empty($task_end_date) && ($task->status!=4 && $task_end_date < $current_date && $task_end_date != '0000-00-00 00:00:00' && $task_end_date != '00-00-0000 00:00:00' && $task_end_date != '00-00-0000' && $task_end_date != '0000-00-00')){
+ $style = "color:#FF2222";
+ } else {
+ $style = "color:#2C3E50";
+ } ?>
+ <td onmouseover="link=true;" class="wppm_table_td"><span style="<?php echo esc_attr($style); ?>"><?php echo isset($wppm_task_duration) ? esc_html($wppm_task_duration):"" ?></span></td>
+ <?php } ?>
</td>
<td onmouseover="link=true;" style="text-align:center;">
<?php
@@ -761,6 +784,10 @@
jQuery('#wppm_chevron_sort_up_end_date_img').show();
jQuery('#wppm_chevron_sort_down_end_date_img').hide();
});
+ jQuery("#wppm_task_duration_th").hover(function(){
+ jQuery('#wppm_chevron_sort_up_task_duration_img').show();
+ jQuery('#wppm_chevron_sort_down_task_duration_img').hide();
+ });
})
jQuery('#wppm_task_list_proj_filter').select2({ dropdownAutoWidth: true, width: 'auto' });
--- a/taskbuilder/includes/class-wppm-functions.php
+++ b/taskbuilder/includes/class-wppm-functions.php
@@ -258,7 +258,8 @@
switch ($permission) {
case 'change_status':
case 'view_task':
- ((!empty($co_worker_array)) && (in_array($current_user->ID,$co_worker_array )) )|| ($current_user->ID == $task_data['created_by']) || $public_proj_meta==1 || ($flag==true) ? $response = true: $response = false;
+ case 'add_task_comment':
+ ((!empty($co_worker_array)) && (in_array($current_user->ID,$co_worker_array )) )|| ($current_user->ID == $task_data['created_by']) || $public_proj_meta==1 || ($flag==true) || $current_user->has_cap('manage_options') ? $response = true: $response = false;
break;
case 'change_task_details':
(($flag==true) || ($current_user->ID == $task_data['created_by']) || $wppm_edit_tasks_permission == 1) ? $response = true: $response = false;
@@ -383,10 +384,19 @@
$co_worker = $project_data['users'];
$co_worker_array = explode(",",(string)$co_worker);
}
+ if(!empty($project_id)){
+ $public_proj_meta = $wpdb->get_var( "SELECT meta_value FROM {$wpdb->prefix}wppm_project_meta where project_id= '$project_id' AND meta_key='public_project'");
+ }else{
+ $public_proj_meta ="";
+ }
+
switch ($permission) {
case 'view_project':
((!empty($co_worker_array)) && (in_array($current_user->ID,$co_worker_array )) )? $response = true: $response = false;
break;
+ case 'add_proj_comment':
+ ( ((!empty($co_worker_array)) && (in_array($current_user->ID,$co_worker_array )) ) || ( $public_proj_meta == '1') || $current_user->has_cap('manage_options')|| $wppm_current_user_capability == 'wppm_admin' || $wppm_current_user_capability == 'wppm_manager')? $response = true: $response = false;
+ break;
case 'change_project_status':
case 'assign_project_users':
case 'change_project_raised_by':
@@ -1127,6 +1137,34 @@
</div>
<?php
}
+
+ public function wppm_get_duration($start_date, $end_date){
+ if ( empty($start_date) || empty($end_date) || $start_date=='0000-00-00 00:00:00' || $end_date =='0000-00-00 00:00:00') {
+ return '';
+ }
+
+ $start_ts = strtotime($start_date);
+ $end_ts = strtotime($end_date);
+
+ if ( $end_ts <= $start_ts ) {
+ return '0 min';
+ }
+
+ $diff = $end_ts - $start_ts;
+
+ $days = floor($diff / 86400);
+ $hours = floor(($diff % 86400) / 3600);
+ $minutes = floor(($diff % 3600) / 60);
+
+ $duration = [];
+
+ if ($days > 0) $duration[] = $days . 'd';
+ if ($hours > 0) $duration[] = $hours . 'h';
+ if ($minutes > 0 || empty($duration)) $duration[] = $minutes . 'm';
+
+ return implode(' ', $duration);
+
+ }
}
endif;
$GLOBALS['wppmfunction'] = new WPPM_Functions();
No newline at end of file
--- a/taskbuilder/includes/wppm-install.php
+++ b/taskbuilder/includes/wppm-install.php
@@ -501,6 +501,11 @@
$wpdb->query("ALTER TABLE `{$wpdb->prefix}wppm_task` ADD `$cl_name` $cl_type");
}
}
+ if($installed_version < '5.0.3'){
+ update_option('wppm_display_time_duration_project',0);
+ update_option('wppm_display_time_duration_task',0);
+
+ }
// update wppm_version option to plugin version
update_option( 'wppm_version', WPPM_VERSION );
}
--- a/taskbuilder/taskbuilder.php
+++ b/taskbuilder/taskbuilder.php
@@ -3,7 +3,7 @@
* Plugin Name: Taskbuilder
* Plugin URI: https://taskbuilder.net/
* Description: Wordpress Project Management & Task Management plugin. Easy to keep track of projects & tasks!
- * Version: 5.0.2
+ * Version: 5.0.3
* Author: Taskbuilder Team
* Author URI: https://taskbuilder.net/
* Requires at least: 4.4
@@ -19,7 +19,7 @@
if ( ! class_exists( 'WP_Taskbuilder' ) ) :
final class WP_Taskbuilder {
- public $version = '5.0.2';
+ public $version = '5.0.3';
public function __construct() {
// define global constants
$this->define_constants();