PluginProbe
Taskbuilder – Project Management & Task Management Tool With Kanban Board / 6.0.6
Taskbuilder – Project Management & Task Management Tool With Kanban Board v6.0.6
6.0.6 6.0.5 6.0.2 6.0.3 6.0.4 6.0.1 6.0.0 5.0.8 5.0.9 4.0.9 5.0.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 All 58 releases
← All changes | includes/admin/tasks/open_task/wppm_open_task.php +684 -178 5.0.26.0.6 View file →
@@ -3,10 +3,12 @@
3 3 exit; // Exit if accessed directly
4 4 }
5 5
6 6 global $current_user,$wpdb,$wppmfunction;
7 -$id = isset($_POST) && isset($_POST['id']) ? intval(sanitize_text_field($_POST['id'])) : "0";
7 +$id = isset($_POST) && isset($_POST['id']) ? intval(sanitize_text_field(wp_unslash($_POST['id']))) : "0";
8 +$page = isset($_POST) && isset($_POST['page']) ? sanitize_text_field(wp_unslash($_POST['page'])) : '';
8 9 $task_list_view = get_option('wppm_default_task_list_view');
10 +$project_id = isset($_POST) && isset($_POST['project_id']) ? intval(sanitize_text_field($_POST['project_id'])) : "0";
9 11 $wppm_default_task_date = get_option('wppm_default_task_date');
10 12 $wppm_task_time = get_option('wppm_task_time');
11 13 $appearance_settings = get_option("wppm-ap-individual-task");
12 14 $wppm_tinymce_visibility_open_task = get_option('wppm_tinymce_visibility_open_task');
@@ -14,15 +16,16 @@
14 16 $wppm_rich_text_editor = get_option('wppm_rich_text_editor');
15 17 $wppm_toolbar_actions = get_option('wppm_toolbar_actions');
16 18 $wppm_date_setting = get_option('wppm_date_setting');
17 19 $wppm_task_hide_comment_section = get_option('wppm_task_hide_comment_section');
20 +$wppm_deafault_time_duration_task = get_option('wppm_display_time_duration_task');
18 21 $url_auth = false;
19 22 $auth_id = $wppmfunction->wppm_get_auth_code($id);
20 23 $auth_id = sanitize_text_field($auth_id);
21 24 // url authentication.
22 -$auth_code = isset( $_POST['auth-code'] ) ? sanitize_text_field( $_POST['auth-code'] ) : ''; // phpcs:ignore
25 +$auth_code = isset( $_POST['auth-code'] ) ? sanitize_text_field( wp_unslash($_POST['auth-code'] ) ) : ''; // phpcs:ignore
23 26 if ( ! $auth_code ) {
24 - $auth_code = isset( $_POST['auth_code'] ) ? sanitize_text_field( $_POST['auth_code'] ) : ''; // phpcs:ignore
27 + $auth_code = isset( $_POST['auth_code'] ) ? sanitize_text_field( wp_unslash($_POST['auth_code'] ) ) : ''; // phpcs:ignore
25 28 }
26 29
27 30 if ( $auth_code && $auth_id == $auth_code ) {
28 31 $url_auth = true;
@@ -27,37 +30,40 @@
27 30 if ( $auth_code && $auth_id == $auth_code ) {
28 31 $url_auth = true;
29 32 }
30 33 if (!(($current_user->ID && $current_user->has_cap('manage_options')) || ($wppmfunction->has_permission('view_task',$id)) || ($url_auth==true))) { ?>
31 - <div style="align-item:center;" ><h6><?php esc_attr_e( 'Unauthorized access!', 'taskbuilder' ); ?></h6></div>
34 + <div style="text-align:center;padding:20px 0;">
35 + <h6><?php esc_attr_e( 'Unauthorized access!', 'taskbuilder' ); ?></h6>
36 + <a href="<?php echo esc_url( admin_url('admin.php?page=wppm-tasks') ); ?>" class="btn btn-success btn-sm"><?php esc_html_e( 'Go to Task List', 'taskbuilder' ); ?></a>
37 + </div>
32 38 <?php
33 39 wp_die();
34 40 }
35 -$proj_id = isset($_POST) && isset($_POST['proj_id']) ? intval(sanitize_text_field($_POST['proj_id'])) : 0;
36 -$current_date = date('Y-m-d');
41 +$proj_id = isset($_POST) && isset($_POST['proj_id']) ? intval(sanitize_text_field(wp_unslash($_POST['proj_id']))) : 0;
42 +$current_date = wp_date('Y-m-d');
37 43 $wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
38 -$cu_id = $current_user->ID;
44 +$cu_id = absint($current_user->ID);
39 45 if(!empty($id)){
40 - $task = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_task where id='".esc_sql($id)."'");
46 + $task = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_task where id=%d",$id));
41 47 $project_data = $wppmfunction->get_project($task->project);
42 - $task_comment = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_task_comment where task_id='".esc_sql($id)."' ORDER BY create_time DESC");
43 - $orderby_proj_sql = esc_sql(sanitize_sql_orderby( "create_time DESC" ));
44 - $task_comment = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_task_comment where task_id='".esc_sql($id)."' ORDER BY ". $orderby_proj_sql);
45 - $task_proj = isset($task->project) ? esc_sql($task->project) :"";
46 - $task_id = isset($task->id) ? esc_sql($task->id):"";
48 + $task_comment = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_task_comment where task_id=%d ORDER BY create_time DESC",$id));
49 + $orderby_proj_sql = (sanitize_sql_orderby( "create_time DESC" ));
50 + $task_comment = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_task_comment where task_id=%d ORDER BY ". $orderby_proj_sql,$id));
51 + $task_proj = isset($task->project) ? absint($task->project) :"";
52 + $task_id = isset($task->id) ? absint($task->id):"";
47 53 }
48 -$user_role = $wpdb->get_var( "SELECT role_id FROM {$wpdb->prefix}wppm_project_users where proj_id = '$task_proj' AND user_id = '$cu_id'");
54 +$user_role = $wpdb->get_var( $wpdb->prepare("SELECT role_id FROM {$wpdb->prefix}wppm_project_users where proj_id = %d AND user_id = %d",$task_proj,$cu_id));
49 55 if(!empty($task_proj)){
50 - $project_name = $wpdb->get_var( "SELECT project_name FROM {$wpdb->prefix}wppm_project where id= '$task_proj'");
56 + $project_name = $wpdb->get_var( $wpdb->prepare("SELECT project_name FROM {$wpdb->prefix}wppm_project where id= %d",$task_proj));
51 57 }
52 -$wppm_checklist=$wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id='$task_id'" );
58 +$wppm_checklist=$wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_checklist where task_id=%d",$task_id));
53 59 if(!empty($task->status)){
54 - $task_status_var = esc_sql($task->status);
55 - $task_status = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_task_statuses where id='$task_status_var'");
60 + $task_status_var = absint($task->status);
61 + $task_status = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_task_statuses where id=%d",$task_status_var));
56 62 }
57 63 if(!empty($task->priority)){
58 - $task_priority_var = esc_sql($task->priority);
59 - $task_priority = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_task_priorities where id='$task_priority_var'");
64 + $task_priority_var = absint($task->priority);
65 + $task_priority = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_task_priorities where id=%d",$task_priority_var));
60 66 }
61 67 if(!empty($task->users)){
62 68 $users = explode(",",$task->users);
63 69 }
@@ -62,9 +68,9 @@
62 68 $users = explode(",",$task->users);
63 69 }
64 70
65 71 if(!empty($task->description)){
66 - $task_description = stripslashes((htmlspecialchars_decode($task->description, ENT_QUOTES)));
72 + $task_description = !empty($task->description) ? wp_kses_post(wpautop($task->description)) : '';
67 73 }
68 74
69 75 if($wppm_task_time == 1){
70 76 $tsDate = new DateTime($task->start_date);
@@ -152,9 +158,9 @@
152 158 }
153 159 }
154 160 }
155 161 $flag = false;
156 -$wppm_task_fillter = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wppm_task where id='".esc_sql($id)."'");
162 +$wppm_task_fillter = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_task where id=%d",$id));
157 163 if(!empty($wppm_task_fillter)){
158 164 foreach($wppm_task_fillter as $key_filter=>$val_filter){
159 165 $val_array = (array) $val_filter;
160 166 $tusers = $val_array['users'];
@@ -159,12 +165,12 @@
159 165 $val_array = (array) $val_filter;
160 166 $tusers = $val_array['users'];
161 167 $tusers_arr = explode(',',$tusers);
162 168 $tproject_id = $val_array['project'];
163 - $tproject_id = esc_sql($tproject_id);
169 + $tproject_id = absint($tproject_id);
164 170 if(!empty($tusers) && in_array($current_user->ID,$tusers_arr)){
165 - $project_user_role = $wpdb->get_var("SELECT role_id FROM {$wpdb->prefix}wppm_project_users WHERE proj_id = '$tproject_id' AND user_id = '$cu_id'");
166 - $project_users = $wpdb->get_var("SELECT users FROM {$wpdb->prefix}wppm_project WHERE id = '$tproject_id'");
171 + $project_user_role = $wpdb->get_var( $wpdb->prepare("SELECT role_id FROM {$wpdb->prefix}wppm_project_users WHERE proj_id = %d AND user_id = %d",$tproject_id,$cu_id));
172 + $project_users = $wpdb->get_var( $wpdb->prepare("SELECT users FROM {$wpdb->prefix}wppm_project WHERE id = %d",$tproject_id));
167 173 $project_users_arr = explode(',',(string)$project_users);
168 174 if((!empty($project_user_role)) && ($project_user_role == 1) && in_array($current_user->ID,$project_users_arr)){
169 175 $flag= true;
170 176 break;
@@ -171,9 +177,9 @@
171 177 }
172 178 }
173 179 }
174 180 }
175 -$project_creator = $wpdb->get_var("SELECT created_by FROM {$wpdb->prefix}wppm_project WHERE created_by = '$cu_id'");
181 +$project_creator = $wpdb->get_var( $wpdb->prepare("SELECT created_by FROM {$wpdb->prefix}wppm_project WHERE created_by = %d",$cu_id));
176 182 ?>
177 183 <form id="wppm_open_task" method="post">
178 184 <div id="wppm_alert_success" class="alert alert-success wppm_alert" style="display:none;" role="alert">
179 185 <img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/success.svg'); ?>" alt="success"> <span class="wppm_alert_text"></span>
@@ -197,29 +203,40 @@
197 203 }else{
198 204 $archive_style= "display:none;";
199 205 }
200 206 if($proj_id==0) {
201 - ?> <span onclick="wppm_add_new_task(<?php echo esc_attr($proj_id) ?>)" class="wppm_add_new_task_btn" id="wppm_add_new_task_btn" style="<?php echo $style?>" title="Create Task"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus.svg'); ?>" alt="add"></span>
207 + ?> <span onclick="wppm_add_new_task(<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)" class="wppm_add_new_task_btn" id="wppm_add_new_task_btn" style="<?php echo esc_attr($style)?>" title="<?php esc_attr_e( 'Create Task', 'taskbuilder' ); ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus.svg'); ?>" alt="add"></span>
202 208 <?php }
203 209 else{ ?>
204 - <span class="wppm_add_new_task_btn" id="wppm_add_new_task_btn" title="Create Task" onclick="wppm_create_project_task(<?php echo esc_attr($proj_id) ?>)" style="<?php echo $style ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus.svg'); ?>" alt="add"></span>
210 + <span class="wppm_add_new_task_btn" id="wppm_add_new_task_btn" title="<?php esc_attr_e( '"Create Task', 'taskbuilder' ); ?>" onclick="wppm_create_project_task(<?php echo esc_attr($proj_id) ?>)" style="<?php echo esc_attr($style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus.svg'); ?>" alt="add"></span>
205 211 <?php } ?>
206 - <?php if($proj_id==0) {
207 - $task_list_function = ($task_list_view==1)?"wppm_get_task_list()":"wppm_view_task_search_filter()";
212 + <?php if($proj_id==0) {
213 + if (($project_id!=0)) {
214 + $task_list_function = "wppm_get_project_tasks_kanban_view( {$project_id})";
215 + }
216 + if (empty($project_id) && $task_list_view == 1) {
217 + $task_list_function = "wppm_get_task_list('', {$project_id})";
218 + }
219 + if(empty($task_list_view) && empty($project_id)) {
220 + $task_list_function = "wppm_view_task_search_filter('', '', {$project_id})";
221 + }
208 222 ?>
209 - <span class="wppm-task-list-btn" id="wppm_task_list_btn" title="Task List" onclick="<?php echo $task_list_function ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list.svg'); ?>" alt="list"></span>
223 + <span class="wppm-task-list-btn" id="wppm_task_list_btn" title="<?php esc_attr_e( 'Task List', 'taskbuilder' ); ?>"onclick="<?php echo esc_attr($task_list_function) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list.svg'); ?>" alt="list"></span>
210 224 <?php }
211 225 else{
212 226 ?>
213 - <span class="wppm-task-list-btn" id="wppm_task_list_btn" title="Task List" onclick="wppm_get_project_tasks(<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list.svg'); ?>" alt="list"></span>
227 + <span class="wppm-task-list-btn" id="wppm_task_list_btn" title="<?php esc_attr_e( 'Task List', 'taskbuilder' ); ?>" onclick="wppm_get_project_tasks(<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list.svg'); ?>" alt="list"></span>
214 228 <?php } ?>
215 - <?php $style = (($current_user->ID && $current_user->has_cap('manage_options')) || ($wppmfunction->has_permission('delete_task',$id)) || $wppm_current_user_capability == 'wppm_admin'|| $project_data['created_by']==$current_user->ID )? "display:inline":"display:none"; ?>
216 - <?php $clone_style = ((($current_user->ID && $current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') || ($wppmfunction->has_permission('clone_task',$id)) || $project_data['created_by']==$current_user->ID ) && $task->is_archived!=1) ? "display:inline":"display:none"; ?>
229 + <?php $style = ((($current_user->ID && $current_user->has_cap('manage_options')) || ($wppmfunction->has_permission('delete_task',$id)) || $wppm_current_user_capability == 'wppm_admin'|| $project_data['created_by']==$current_user->ID ) && $user_role != 3) ? "display:inline":"display:none"; ?>
230 + <?php $clone_style = ((($current_user->ID && $current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') || ($wppmfunction->has_permission('clone_task',$id)) || $project_data['created_by']==$current_user->ID ) && $task->is_archived!=1 && $user_role != 3) ? "display:inline":"display:none"; ?>
217 231 <?php $ar_css = ($task->is_archived==1) ? "display:none;" : "display:inline"; ?>
218 - <span class="wppm-delete_task_btn" id="wppm_delete_task_btn" title="Delete Task" onclick="wppm_get_delete_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)" style="<?php echo esc_attr($style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/bin.svg'); ?>" alt="delete"></span>
219 - <div class="wppm-clone_task_btn" id="wppm_clone_task_btn" title="Clone Task" onclick="wppm_clone_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id)?>)" style="<?php echo esc_attr($clone_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/duplicate.svg'); ?>" alt="clone"></div>
232 + <span class="wppm-dashboard-btn" id="wppm_dashboard_btn" title="<?php esc_attr_e( 'Dashboard', 'taskbuilder' ); ?>" onclick="wppm_get_project_tasks(<?php echo esc_attr($proj_id) ?>)">
233 + <a href="<?php echo esc_url(admin_url('admin.php?page=wppm-dashboard')); ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/dashboard-icon.svg'); ?>" alt="dashboard"></a>
234 + </span>
235 + <span class="wppm-delete_task_btn" id="wppm_delete_task_btn" title="Delete Task" onclick="wppm_get_delete_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)" style="<?php echo esc_attr($style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/bin.svg'); ?>" alt="delete"></span>
236 + <span class="wppm-clone_task_btn" id="wppm_clone_task_btn" title="Clone Task" onclick="wppm_clone_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id)?>,<?php echo esc_attr($project_id) ?>)" style="<?php echo esc_attr($clone_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/duplicate.svg'); ?>" alt="clone"></span>
220 237 <span class="wppm-print_task_btn" id="wppm_print_task_btn" title="Print Task" onclick="wppm_print_task(<?php echo esc_attr($id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/printer_menu.svg'); ?>" alt="print" style="<?php echo esc_attr($ar_css);?>"></span>
221 - <span class="wppm-archieve_task_btn" id="wppm_archieve_task_btn" title="<?php echo ($task->is_archived==1 ) ? 'Restore Task' : 'Archive Task'; ?>" onclick="wppm_archive_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($task->is_archived) ?>)" style="<?php echo esc_attr($archive_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/archive.svg'); ?>" alt="archive"></span>
238 + <span class="wppm-archieve_task_btn" id="wppm_archieve_task_btn" title="<?php echo ($task->is_archived==1 ) ? 'Restore Task' : 'Archive Task'; ?>" onclick="wppm_archive_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($task->is_archived) ?>,<?php echo esc_attr($project_id) ?>)" style="<?php echo esc_attr($archive_style) ?>"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/archive.svg'); ?>" alt="archive"></span>
222 239 <input type="hidden" name="wppm_archive_task_ajax_nonce" id="wppm_archive_task_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_archive_task_ajax_nonce' ) ); ?>">
223 240 <div class="menu" id="wppmprint_menu" onclick="event.stopPropagation();">
224 241 <a href="#" id="wppm_openPDF" onclick="wppm_open_pdf(<?php echo esc_attr($id) ?>)">🖨️ <?php echo esc_html_e('Open In Browser','taskbuilder');?></a>
225 242 <a href="#" id="wppm_downloadPDF" onclick="wppm_download_pdf(<?php echo esc_attr($id) ?>)">💾 <?php echo esc_html_e('Download PDF','taskbuilder');?></a>
@@ -224,9 +241,9 @@
224 241 <a href="#" id="wppm_openPDF" onclick="wppm_open_pdf(<?php echo esc_attr($id) ?>)">🖨️ <?php echo esc_html_e('Open In Browser','taskbuilder');?></a>
225 242 <a href="#" id="wppm_downloadPDF" onclick="wppm_download_pdf(<?php echo esc_attr($id) ?>)">💾 <?php echo esc_html_e('Download PDF','taskbuilder');?></a>
226 243 </div>
227 244 <?php do_action('wppm_individual_task_button',$id);?>
228 - </div>
245 + </div>
229 246 </div>
230 247 <div id="wppm_load_individual_task_container" class="row">
231 248 <div class="col-sm-8 wppm_body col-md-9">
232 249 <div class="wppm_task_details_container">
@@ -231,13 +248,28 @@
231 248 <div class="col-sm-8 wppm_body col-md-9">
232 249 <div class="wppm_task_details_container">
233 250 <div class="row">
234 251 <div class="col-sm-12">
235 - <span class="wppm_task_label"> <?php echo esc_html_e($task->task_name,'taskbuilder');
236 - if (($wppmfunction->has_permission('change_task_details',$id) || $current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') && $task->is_archived!=1) { ?>
237 - <span id="wppm_individual_edit_task_subject" onclick="wppm_edit_task_details(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)" class="btn btn-sm wppm_action_btn" style="background-color:#FFFFFF !important;color:#000000 !important;"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
252 + <span class="wppm_task_label"> <?php echo isset($task->task_name) ? esc_html($task->task_name ):"" ?>
253 + <?php if (($wppmfunction->has_permission('change_task_details',$id) || $current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') && $task->is_archived!=1) { ?>
254 + <span id="wppm_individual_edit_task_subject" onclick="wppm_edit_task_details(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)" class="btn btn-sm wppm_action_btn" style="background-color:#FFFFFF !important;color:#000000 !important;"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
238 255 <?php } ?>
239 256 </span>
257 + <?php if(!empty($task->parent_task_id)){
258 + $wppm_parent_task = $wpdb->get_row( $wpdb->prepare("SELECT id, task_name FROM {$wpdb->prefix}wppm_task where id=%d",absint($task->parent_task_id)));
259 + if(!empty($wppm_parent_task)){
260 + $wppm_can_convert_subtask = (($current_user->has_cap('manage_options') || $wppmfunction->has_permission('delete_task',$id)) && $task->is_archived!=1);
261 + ?>
262 + <div class="wppm_subtask_parent_link">
263 + <?php echo esc_html_e('Subtask of','taskbuilder');?>
264 + <a href="#" onclick="wppm_open_subtask(<?php echo esc_attr($wppm_parent_task->id) ?>,<?php echo esc_attr($proj_id) ?>);return false;"><?php echo esc_html($wppm_parent_task->task_name); ?></a>
265 + <?php if($wppm_can_convert_subtask){ ?>
266 + &nbsp;|&nbsp;<a href="#" onclick="wppm_convert_subtask_to_task(<?php echo esc_attr($id) ?>,<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>);return false;"><?php echo esc_html_e('Convert to Task','taskbuilder');?></a>
267 + <input type="hidden" name="wppm_convert_subtask_to_task_ajax_nonce" id="wppm_convert_subtask_to_task_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_convert_subtask_to_task' ) ); ?>">
268 + <?php } ?>
269 + </div>
270 + <?php }
271 + } ?>
240 272 </div>
241 273 </div>
242 274 <div class="row">
243 275 <div class="col-sm-3">
@@ -243,9 +275,9 @@
243 275 <div class="col-sm-3">
244 276 <span class="wppm_task_details_label"><?php echo esc_html_e('Project:','taskbuilder');?></span>
245 277 </div>
246 278 <div class="col-sm-9">
247 - <span class="wppm_task_details"><?php echo (isset($project_name))? esc_html_e($project_name,'taskbuilder'):"" ?></span>
279 + <span class="wppm_task_details"><?php echo (isset($project_name))? esc_html($project_name ):"" ?></span>
248 280 </div>
249 281 </div>
250 282 <div class="row">
251 283 <div class="col-sm-3">
@@ -276,9 +308,9 @@
276 308 } ?>
277 309 <span class="wppm_task_details"><?php echo (isset($task_create_date))? esc_html($task_create_date):"" ?></span>
278 310 </div>
279 311 </div>
280 - <?php if($wppm_default_task_date == 1){ ?>
312 + <?php if($wppm_default_task_date == 1 && $wppm_deafault_time_duration_task==0){ ?>
281 313 <div class="row">
282 314 <div class="col-sm-3">
283 315 <span class="wppm_task_details_label"><?php echo esc_html_e('Start Date:','taskbuilder');?></span>
284 316 </div>
@@ -296,15 +328,28 @@
296 328 <span class="wppm_task_details" id="wppm_edit_tend_date" style="<?php echo esc_attr($style); ?>"><?php echo (isset($task_end_date))? esc_html($task_end_date):"" ?></span>
297 329 </div>
298 330 <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' ) ); ?>">
299 331 </div>
300 - <?php } ?>
332 + <?php }
333 + if($wppm_deafault_time_duration_task==1){
334 + $wppm_task_duration = $wppmfunction->wppm_get_duration($task->start_date,$task->end_date);
335 + $tstatus = isset($task->status) ? $task->status :"";
336 + $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"; ?>
337 + <div class="row">
338 + <div class="col-sm-3">
339 + <span class="wppm_task_details_label"><?php echo esc_html_e('Task Duration:','taskbuilder');?></span>
340 + </div>
341 + <div class="col-sm-9">
342 + <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>
343 + </div>
344 + </div> <?php
345 + }?>
301 346 <div class="row">
302 347 <div class="col-sm-3">
303 348 <span class="wppm_task_details_label"><?php echo esc_html_e('Task Priority:','taskbuilder');?></span>
304 349 </div>
305 350 <div class="col-sm-9">
306 - <span class="wppm_task_details_priority"><span class="wppm_admin_label" style="background-color:<?php echo (isset($task_priority->bg_color))? esc_html($task_priority->bg_color):""?>;color:<?php echo (isset($task_priority->color))? esc_html($task_priority->color):""?>;"><?php echo (isset($task_priority->name)) ? esc_html_e($task_priority->name,'taskbuilder'):"" ?> </span></span>
351 + <span class="wppm_task_details_priority"><span class="wppm_admin_label" style="background-color:<?php echo (isset($task_priority->bg_color))? esc_html($task_priority->bg_color):""?>;color:<?php echo (isset($task_priority->color))? esc_html($task_priority->color):""?>;"><?php echo (isset($task_priority->name)) ? esc_html($task_priority->name):"" ?> </span></span>
307 352 </div>
308 353 </div>
309 354 <div class="row">
310 355 <div class="col-sm-3">
@@ -310,13 +355,173 @@
310 355 <div class="col-sm-3">
311 356 <span class="wppm_task_details_label"><?php echo esc_html_e('Description:','taskbuilder');?></span>
312 357 </div>
313 358 <div class="col-sm-9">
314 - <span class="wppm_task_description"><?php echo (isset($task_description))? wp_kses_post(wpautop($task_description)):"" ?></span>
359 + <span class="wppm_task_description"><?php echo (!empty($task_description))? wp_kses_post(wpautop($task_description)):"" ?></span>
315 360 </div>
316 361 </div>
317 362 <?php do_action('wppm_after_task_details_in_open_task',$task->id, $task->project);?>
318 363 </div>
364 + <?php if(empty($task->parent_task_id)){
365 + $wppm_subtasks = $wppmfunction->get_subtasks($task_id);
366 + $wppm_subtask_progress = $wppmfunction->get_subtask_progress($task_id);
367 + $wppm_default_task_status = get_option('wppm_default_task_status');
368 + $wppm_can_add_subtask = (($current_user->has_cap('manage_options') || $wppmfunction->has_permission('add_new_task',$task_id)) && $task->is_archived!=1 && $user_role != 3);
369 + ?>
370 + <div class="wppm_task_subtask_container" id="wppm_task_subtask_container">
371 + <div class="row">
372 + <div class="col-sm-8">
373 + <span class="wppm_checklist_label"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/task_list.svg'); ?>" alt="subtasks"><?php echo esc_html_e('Subtasks','taskbuilder');?></span>
374 + </div>
375 + </div>
376 + <?php if($wppm_subtask_progress['total'] > 0){
377 + $wppm_subtask_percent = round(($wppm_subtask_progress['completed'] / $wppm_subtask_progress['total']) * 100); ?>
378 + <div class="wppm_progress_bar_container row">
379 + <div class="col-sm-4">
380 + <span class="wppm_progressbar_label" id="wppm_subtask_progress_label"><?php echo esc_html($wppm_subtask_progress['completed'].'/'.$wppm_subtask_progress['total']); ?></span>
381 + </div>
382 + <div class="wppm_progress_bar col-sm-8">
383 + <div id="wppm_subtask_progressbar" class="wppm_checkprogress" role="progressbar" style="width: <?php echo esc_attr($wppm_subtask_percent); ?>%;background:#5ba4cf;" aria-valuemin="0" aria-valuemax="100"></div>
384 + </div>
385 + </div>
386 + <?php } ?>
387 + <input type="hidden" name="wppm_set_change_task_status_ajax_nonce" id="wppm_subtask_status_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_set_change_task_status' ) ); ?>">
388 + <input type="hidden" name="wppm_add_new_subtask_ajax_nonce" id="wppm_add_new_subtask_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_add_new_subtask' ) ); ?>">
389 + <input type="hidden" name="wppm_remove_subtask_ajax_nonce" id="wppm_remove_subtask_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_remove_subtask' ) ); ?>">
390 + <input type="hidden" name="wppm_convert_subtask_to_task_ajax_nonce" id="wppm_convert_subtask_to_task_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_convert_subtask_to_task' ) ); ?>">
391 + <ul id="wppm_subtask_items_container" class="wppm_checklist_items_container" style="list-style-type: none; padding-left:0px; margin-top:10px; margin-bottom:10px;">
392 + <?php if(!empty($wppm_subtasks)){
393 + foreach($wppm_subtasks as $subtask){
394 + $wppm_subtask_checked = ($subtask['status']==4) ? 'checked="checked"' : '';
395 + $wppm_subtask_users = !empty($subtask['users']) ? explode(",",$subtask['users']) : array();
396 + $wppm_subtask_can_change_status = ($current_user->has_cap('manage_options') || $wppmfunction->has_permission('change_status',$subtask['id'])) && $task->is_archived!=1;
397 + $wppm_subtask_can_delete = ($current_user->has_cap('manage_options') || $wppmfunction->has_permission('delete_task',$subtask['id'])) && $task->is_archived!=1;
398 + ?>
399 + <li id="wppm_subtask_<?php echo esc_attr($subtask['id']) ?>" class="row wppm_checklist_item" style="margin-bottom:10px;font: 15px 'Helvetica Neue',Helvetica,Arial,sans-serif;">
400 + <div class="col-sm-8">
401 + <input id="wppm_subtask_checkbox_<?php echo esc_attr($subtask['id']) ?>" type="checkbox" onchange="wppm_toggle_subtask_status(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($task_id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($wppm_default_task_status) ?>,this.checked)" <?php echo esc_attr($wppm_subtask_checked) ?> <?php echo $wppm_subtask_can_change_status ? '' : 'disabled'; ?> style="margin:5px;">
402 + <label style="padding-top: 5px;font-weight: normal;font: 13px 'Helvetica Neue',Helvetica,Arial,sans-serif;cursor:pointer;" onclick="wppm_open_subtask(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($proj_id) ?>)"><?php echo esc_html($subtask['task_name']); ?></label>
403 + </div>
404 + <div class="col-sm-4" style="text-align:right;">
405 + <?php $wppm_subtask_avatar_count = 0;
406 + $wppm_subtask_total_users = count( array_filter( $wppm_subtask_users ) );
407 + foreach($wppm_subtask_users as $wppm_subtask_user_id){
408 + if(!$wppm_subtask_user_id) continue;
409 + $wppm_subtask_avatar_count++;
410 + if($wppm_subtask_avatar_count > 3) break;
411 + $wppm_subtask_user_data = get_userdata($wppm_subtask_user_id);
412 + $wppm_subtask_user_name = !empty($wppm_subtask_user_data) ? $wppm_subtask_user_data->display_name : '';
413 + echo get_avatar($wppm_subtask_user_id, 20, "mysteryman", $wppm_subtask_user_name, array('extra_attr' => 'title="'.esc_attr($wppm_subtask_user_name).'"'));
414 + }
415 + $wppm_subtask_more_users = $wppm_subtask_total_users - 3;
416 + if ( $wppm_subtask_more_users > 0 ) {
417 + ?>
418 + <span class="wppm_subtask_more_users" title="<?php echo esc_attr( sprintf( _n( '%d more user assigned', '%d more users assigned', $wppm_subtask_more_users, 'taskbuilder' ), $wppm_subtask_more_users ) ); ?>">+<?php echo esc_html( $wppm_subtask_more_users ); ?></span>
419 + <?php
420 + } ?>
421 + <?php if($wppm_subtask_can_delete){ ?>
422 + <a href="#" title="<?php echo esc_attr__('Convert to Task','taskbuilder'); ?>" onclick="wppm_convert_subtask_to_task(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($task_id) ?>,<?php echo esc_attr($proj_id) ?>);return false;" style="font-size:11px;margin-right:8px;"><?php echo esc_html_e('Convert to Task','taskbuilder');?></a>
423 + <span onclick="wppm_delete_subtask(<?php echo esc_attr($subtask['id']) ?>,<?php echo esc_attr($task_id) ?>,<?php echo esc_attr($proj_id) ?>)" style="cursor:pointer;"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/trash.svg'); ?>" alt="delete"></span>
424 + <?php } ?>
425 + </div>
426 + </li>
427 + <?php
428 + }
429 + } ?>
430 + </ul>
431 + <?php if($wppm_can_add_subtask){
432 + $wppm_all_task_statuses = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wppm_task_statuses ORDER BY load_order ASC");
433 + ?>
434 + <div class="row">
435 + <div class="col-sm-12" style="padding-top:15px;">
436 + <a class="wppm_add_checklist" id="wppm_add_subtask_btn" onclick="wppm_show_add_subtask()"><?php echo esc_html_e('+ Add subtask','taskbuilder');?></a>
437 + </div>
438 + </div>
439 + <div class="row">
440 + <div class="col-sm-12" style="display:none;" id="wppm_add_subtask_label_container">
441 + <div class="row">
442 + <div class="wppm_task_frm_fields col-sm-6">
443 + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Subtask Name','taskbuilder');?></b> <span style="color:#ff0000;">*</span></span><br>
444 + <input type="text" id="wppm_subtask_label" class="form-control" placeholder="<?php echo esc_attr__('Subtask name','taskbuilder') ?>" name="wppm_subtask_label">
445 + </div>
446 + <div class="wppm_task_frm_fields col-sm-6">
447 + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Status','taskbuilder');?></b></span><br>
448 + <select id="wppm_subtask_status" name="wppm_subtask_status" class="form-control">
449 + <?php if(!empty($wppm_all_task_statuses)){
450 + foreach($wppm_all_task_statuses as $wppm_st){ ?>
451 + <option value="<?php echo esc_attr($wppm_st->id) ?>" <?php selected($wppm_st->id, $wppm_default_task_status); ?>><?php echo esc_html($wppm_st->name) ?></option>
452 + <?php }
453 + } ?>
454 + </select>
455 + </div>
456 + </div>
457 + <div class="row">
458 + <div class="wppm_task_frm_fields col-sm-6">
459 + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Due date','taskbuilder');?></b></span><br>
460 + <input type="text" id="wppm_subtask_due_date" class="form-control" name="wppm_subtask_due_date" value="" autocomplete="off">
461 + </div>
462 + <div class="wppm_task_frm_fields col-sm-6">
463 + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Assignee','taskbuilder');?></b></span><br>
464 + <input class="form-control wppm_subtask_assign_users ui-autocomplete-input" name="wppm_subtask_assign_users" type="text" autocomplete="off" placeholder="<?php echo esc_attr__('Search User...','taskbuilder');?>">
465 + </div>
466 + </div>
467 + <div class="row">
468 + <div class="col-sm-12">
469 + <ul class="wppm_subtask_filter_display_users_container" style="list-style:none;padding-left:0;"></ul>
470 + </div>
471 + </div>
472 + <div class="row">
473 + <div class="wppm_task_frm_fields col-sm-12">
474 + <span class="wppm_form_field_label"><b><?php echo esc_html_e('Description','taskbuilder');?></b></span><br>
475 + <textarea id="wppm_subtask_description" name="wppm_subtask_description" class="form-control" rows="3"></textarea>
476 + </div>
477 + </div>
478 + <div class="row" style="padding-top:10px;">
479 + <div class="col-sm-12">
480 + <input type="button" value="<?php echo esc_attr__('Add','taskbuilder') ?>" class="btn btn-success btn-sm" onclick="wppm_add_new_subtask(<?php echo esc_attr($task_id)?>,<?php echo esc_attr($proj_id) ?>)">
481 + <button type="button" class="wppm_reset_btn" onclick="wppm_hide_add_subtask()"><?php echo esc_html_e('Cancel','taskbuilder');?></button>
482 + </div>
483 + </div>
484 + </div>
485 + </div>
486 + <script type="text/javascript">
487 + jQuery(document).ready(function(){
488 + jQuery('#wppm_subtask_due_date').flatpickr({
489 + enableTime: true,
490 + dateFormat: "Y-m-d H:i"
491 + });
492 + jQuery('.wppm_subtask_assign_users').autocomplete({
493 + minLength: 1,
494 + appendTo: jQuery('.wppm_subtask_assign_users').parent(),
495 + source: function(request, response){
496 + jQuery.getJSON(wppm_admin.ajax_url, {
497 + action: 'wppm_filter_autocomplete',
498 + term: request.term,
499 + field: 'task_users_by_project_name',
500 + proj_id: <?php echo (int) $task->project; ?>
501 + }, function(data){ response(data); });
502 + },
503 + select: function(event, ui){
504 + if(!ui.item.user_id){ return false; }
505 + var html_str = '<li class="wppm_filter_display_element" style="list-style:none">'
506 + +'<div class="flex-container">'
507 + +'<div class="wppm_filter_display_text">'
508 + + ui.item.label
509 + + '<input type="hidden" name="wppm_subtask_user_names[]" value="'+ui.item.user_id+'">'
510 + +'</div>'
511 + +'<div class="wppm_filter_display_remove" onclick="wppm_remove_subtask_user(this);"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cross.svg'); ?>" alt="delete"></div>'
512 + +'</div>'
513 + +'</li>';
514 + jQuery('.wppm_subtask_filter_display_users_container').append(html_str);
515 + jQuery(this).val('');
516 + return false;
517 + }
518 + }).focus(function(){ jQuery(this).autocomplete("search", ""); });
519 + });
520 + </script>
521 + <?php } ?>
522 + </div>
523 + <?php } ?>
319 524 <div class="wppm_task_checklist_container" id="wppm_task_checklist_container">
320 525 <div id="wppm_checklist_container">
321 526 <?php
322 527 if(!empty($wppm_checklist)){
@@ -323,9 +528,9 @@
323 528 foreach( $wppm_checklist as $key=>$list){
324 529 ?>
325 530 <div class="row">
326 531 <div class="col-sm-8">
327 - <span class="wppm_checklist_label"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/checklist.svg'); ?>" alt="checklist"><?php echo esc_html_e($list->checklist_name,'taskbuilder');?></span>
532 + <span class="wppm_checklist_label"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/checklist.svg'); ?>" alt="checklist"><?php echo isset($list->checklist_name) ? esc_html($list->checklist_name):"" ?></span>
328 533 </div>
329 534 <?php
330 535 $check_style = (($list->created_by == $current_user->ID || $current_user->has_cap('manage_options') || $user_role == 1 || $wppmfunction->has_permission('edit_checklist',$task->id)) && $task->is_archived!=1)? "display:inline":"display:none"; ?>
331 536 <?php $disabled = (($list->created_by == $current_user->ID || $current_user->has_cap('manage_options') || $user_role == 1 || $wppmfunction->has_permission('delete_checklist',$task->id)|| ($wppmfunction->has_permission('add_checklist',0))) && $task->is_archived!=1)? "":"disabled"; ?>
@@ -344,10 +549,18 @@
344 549 <div id="CheckProgress_<?php echo esc_attr($list->id);?>" class="wppm_checkprogress" role="progressbar" style="width: 0%" aria-valuemin="0" aria-valuemax="100"></div>
345 550 </div>
346 551 </div>
347 552 <?php
348 - $list_id = esc_sql($list->id);
349 - $wppm_checklist_items = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_checklist_items where checklist_id='$list_id' ORDER BY load_order ASC");
553 + $list_id = absint($list->id);
554 + $sql = $wpdb->prepare(
555 + "SELECT *
556 + FROM {$wpdb->prefix}wppm_checklist_items
557 + WHERE checklist_id = %d
558 + ORDER BY load_order ASC",
559 + $list_id
560 + );
561 + // Execute
562 + $wppm_checklist_items = $wpdb->get_results($sql);
350 563 ?>
351 564 <ul id="wppm_checklist_items_container_<?php echo esc_attr($list->id) ?>" class="wppm_checklist_items_container" style="list-style-type: none; padding-left:0px; margin-top:10px; margin-bottom:10px;">
352 565 <?php
353 566 if(!empty( $wppm_checklist_items)){
@@ -356,9 +569,9 @@
356 569 ?>
357 570 <li id="wppm_checklist_<?php echo esc_attr($val->id) ?>" data-id="<?php echo esc_attr($val->id); ?>" class="row wppm_checklist_item" style="margin-bottom:10px;font: 15px 'Helvetica Neue',Helvetica,Arial,sans-serif;">
358 571 <div class="col-sm-8" id="wppm_checklist_item_container_<?php echo esc_attr($val->id) ?>">
359 572 <span class="wppm_chk_items_drag">☰</span>
360 - <input id="wppm_checklist_item_<?php echo esc_attr($val->id) ?>" class="wppm_checklist_item_<?php echo esc_attr($val->checklist_id) ?>" onchange="wppm_checklist_progress(<?php echo esc_attr($val->checklist_id) ?>,<?php echo esc_attr($val->id) ?>,<?php echo esc_attr($task->id) ?>)" type="checkbox" name="wppm_checklist" <?php echo esc_attr($checked) ?> value="<?php echo esc_attr($val->id) ?>" <?php echo esc_attr($disabled) ?> style="margin:5px;"><label style="padding-top: 5px;font-weight: normal;font: 13px 'Helvetica Neue',Helvetica,Arial,sans-serif;"><?php echo esc_html_e($val->item_name,'taskbuilder') ?></label>
573 + <input id="wppm_checklist_item_<?php echo esc_attr($val->id) ?>" class="wppm_checklist_item_<?php echo esc_attr($val->checklist_id) ?>" onchange="wppm_checklist_progress(<?php echo esc_attr($val->checklist_id) ?>,<?php echo esc_attr($val->id) ?>,<?php echo esc_attr($task->id) ?>)" type="checkbox" name="wppm_checklist" <?php echo esc_attr($checked) ?> value="<?php echo esc_attr($val->id) ?>" <?php echo esc_attr($disabled) ?> style="margin:5px;"><label style="padding-top: 5px;font-weight: normal;font: 13px 'Helvetica Neue',Helvetica,Arial,sans-serif;"><?php echo isset($val->item_name) ? esc_html($val->item_name) : "" ?></label>
361 574 <input type="hidden" name="wppm_checklist_progress_ajax_nonce" id="wppm_checklist_progress_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_set_checklist_progress' ) ); ?>">
362 575 </div>
363 576 <?php if (($list->created_by == $current_user->ID || $current_user->has_cap('manage_options') || $user_role == 1 || $wppmfunction->has_permission('delete_checklist',$task->id)) && $task->is_archived!=1) { ?>
364 577 <div class="col-sm-4" id="wppm_checklist_action_<?php echo esc_attr($val->id) ?>" style="text-align:right; display:none;cursor:pointer;">
@@ -399,28 +612,30 @@
399 612 <?php
400 613 }
401 614 } ?>
402 615 </div><?php
403 - if(($wppmfunction->has_permission('add_checklist',$task->id) || $current_user->has_cap('manage_options')) && $task->is_archived!=1){ ?>
404 - <div id="wppm_add_checklist_container">
405 - <div class="row">
406 - <div class="col-sm-12">
407 - <span id="wppm_add_checklist" onclick="wppm_add_checklist()"> <?php echo esc_html_e('+Add a checklist','taskbuilder')?> </span>
616 + if($user_role != 3){
617 + if(($wppmfunction->has_permission('add_checklist',$task->id) || $current_user->has_cap('manage_options')) && $task->is_archived!=1){ ?>
618 + <div id="wppm_add_checklist_container">
619 + <div class="row">
620 + <div class="col-sm-12">
621 + <span id="wppm_add_checklist" onclick="wppm_add_checklist()"> <?php echo esc_html_e('+Add a checklist','taskbuilder')?> </span>
622 + </div>
408 623 </div>
409 - </div>
410 - <div class="row" id="wppm_add_new_checklist" style="display:none;">
411 - <div class="col-sm-12">
412 - <input type="text" class="wppm_checklist_label" placeholder="<?php echo esc_attr__('Please insert checklist title','taskbuilder');?>" id="wppm_checklist_label" name="wppm_checklist_label">
413 - <input type="button" value="Add" id="wppm_checklist_btn" class="btn btn-success btn-sm" onclick="wppm_add_new_checklist(<?php echo esc_attr($id)?>,<?php echo esc_attr($proj_id) ?>)">
414 - <input type="hidden" name="wppm_checklist_ajax_nonce" id="wppm_checklist_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_add_new_checklist' ) ); ?>">
415 - <span onclick="wppm_remove_add_checklist()"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cross1.svg'); ?>"></span>
624 + <div class="row" id="wppm_add_new_checklist" style="display:none;">
625 + <div class="col-sm-12">
626 + <input type="text" class="wppm_checklist_label" placeholder="<?php echo esc_attr__('Please insert checklist title','taskbuilder');?>" id="wppm_checklist_label" name="wppm_checklist_label">
627 + <input type="button" value="Add" id="wppm_checklist_btn" class="btn btn-success btn-sm" onclick="wppm_add_new_checklist(<?php echo esc_attr($id)?>,<?php echo esc_attr($proj_id) ?>)">
628 + <input type="hidden" name="wppm_checklist_ajax_nonce" id="wppm_checklist_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_add_new_checklist' ) ); ?>">
629 + <span onclick="wppm_remove_add_checklist()"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cross1.svg'); ?>"></span>
630 + </div>
416 631 </div>
417 - </div>
418 - </br>
419 - </div><?php
420 - } ?>
632 + </br>
633 + </div><?php
634 + }
635 + }?>
421 636 </div>
422 - <div id="wppm_activity_container" style="<?php echo ($wppm_task_hide_comment_section==0) ? 'display:none;' : 'display:block;' ?>">
637 + <div id="wppm_activity_container" style="<?php echo ($wppm_task_hide_comment_section==0 || $user_role==3) ? 'display:none;' : 'display:block;' ?>">
423 638 <div class="row">
424 639 <div class="col-sm-12" style="margin-top:5px;">
425 640 <span class="wppm_task_discussion"><?php echo esc_html_e('Comment','taskbuilder')?></span><br>
426 641 </div>
@@ -448,18 +663,25 @@
448 663 <div class="wppm_attachment_container col-sm-12" style="display:none;">
449 664 </div>
450 665 </div>
451 666 </div>
452 - <div class="wppm_thread_container" style="<?php echo ($wppm_task_hide_comment_section==0) ? 'display:none;' : 'display:block;' ?>">
667 + <div class="wppm_thread_container" style="<?php echo ($wppm_task_hide_comment_section==0 || $user_role==3) ? 'display:none;' : 'display:block;' ?>">
453 668 <?php
454 669 if(!empty($task_comment)){
455 670 foreach($task_comment as $comment){
456 - $task_comment_meta = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_task_comment_meta where task_id='".esc_sql($id)."' AND comment_id='".esc_sql($comment->id)."'");
671 + $task_comment_meta = $wpdb->get_row( $wpdb->prepare(
672 + "SELECT *
673 + FROM {$wpdb->prefix}wppm_task_comment_meta
674 + WHERE task_id = %d
675 + AND comment_id = %d",
676 + absint($id),
677 + absint($comment->id)
678 + )
679 + );
457 680 $user = get_userdata( $comment->created_by );
458 - $comment_body = stripslashes((htmlspecialchars_decode($comment->body, ENT_QUOTES)));
459 - $comment_body = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $comment_body);
460 - $date = date("Y-m-d H:i:s" ,strtotime($comment->create_time));
461 - $thread_date = date("d F Y, h:i:s A" ,strtotime($date));
681 + $comment_body = (!empty($comment->body) ? ($comment->body) : '');
682 + $date = wp_date("Y-m-d H:i:s" ,strtotime($comment->create_time));
683 + $thread_date = wp_date("d F Y, h:i:s A" ,strtotime($date));
462 684 $attachment_ids = isset($comment->attachment_ids)? $comment->attachment_ids : '';
463 685 if($attachment_ids!=""){
464 686 $attachments = explode(",",$attachment_ids);
465 687 } else {
@@ -471,22 +693,30 @@
471 693 <?php echo (get_avatar($comment->created_by, 40));?>
472 694 </div>
473 695 <div class="wppm_thread_body">
474 696 <div class="wppm_thread_user_name">
475 - <strong style="color:<?php echo esc_attr($appearance_settings['comment-primary-color']);?>"><?php echo esc_html($user->display_name) ?></strong>
697 + <strong style="color:<?php echo esc_attr($appearance_settings['comment-primary-color']);?>"><?php echo isset($user->display_name) ? esc_html($user->display_name) : '' ?></strong>
476 698 <span><?php if(!empty($comment->body) && (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='change_task_status')){
477 699 $comment_log_body = unserialize($comment->body);
478 700 $prev_status = $comment_log_body['prev_status'];
479 701 $new_status = $comment_log_body['new_status'];
480 702 if(isset($prev_status)){
481 - $prev_status = esc_sql($prev_status);
482 - $task_prev_status = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}wppm_task_statuses where id='$prev_status'");
703 + $task_prev_status = $wpdb->get_row( $wpdb->prepare(
704 + "SELECT * FROM {$wpdb->prefix}wppm_task_statuses where id = %d",
705 + absint($prev_status)
706 + ));
483 707 }
484 708 if(isset($new_status)){
485 - $new_status = esc_sql($new_status);
486 - $task_new_status = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}wppm_task_statuses where id='$new_status'");
709 + $task_new_status = $wpdb->get_row( $wpdb->prepare(
710 + "SELECT * FROM {$wpdb->prefix}wppm_task_statuses where id = %d",
711 + absint($new_status)
712 + ));
487 713 }
488 - esc_html_e("changed status from $task_prev_status->name to $task_new_status->name","taskbuilder");
714 + printf(
715 + esc_html__( 'Changed status from %1$s to %2$s', 'taskbuilder' ),
716 + esc_html( $task_prev_status->name ),
717 + esc_html( $task_new_status->name )
718 + );
489 719 } if(!empty($comment->body) && (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='change_task_creator')){
490 720 $comment_log_body = unserialize($comment->body);
491 721 $prev_user = $comment_log_body['prev_user'];
492 722 $new_user = $comment_log_body['new_user'];
@@ -491,9 +721,13 @@
491 721 $prev_user = $comment_log_body['prev_user'];
492 722 $new_user = $comment_log_body['new_user'];
493 723 $prev_user_data = get_userdata($prev_user);
494 724 $new_user_data = get_userdata($new_user);
495 - esc_html_e("changed creator from $prev_user_data->display_name to $new_user_data->display_name","taskbuilder");
725 + printf(
726 + esc_html__( 'Changed creator from %1$s to %2$s', 'taskbuilder' ),
727 + esc_html( $prev_user_data->display_name ),
728 + esc_html( $new_user_data->display_name )
729 + );
496 730 }
497 731 if( !empty($comment->body) && (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='change_assign_user')){
498 732 esc_html_e("changed the Assignee","taskbuilder");
499 733 }
@@ -501,21 +735,31 @@
501 735 $comment_log_body = unserialize($comment->body);
502 736 $prev_prio = $comment_log_body['prev_prio'];
503 737 $new_prio = $comment_log_body['new_prio'];
504 738 if(isset($prev_prio)){
505 - $prev_prio = esc_sql($prev_prio);
506 - $task_prev_prio = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}wppm_task_priorities where id= '$prev_prio'");
739 + $prev_prio = absint($prev_prio);
740 + $task_prev_prio = $wpdb->get_row( $wpdb->prepare(
741 + "SELECT * FROM {$wpdb->prefix}wppm_task_priorities where id = %d",
742 + $prev_prio
743 + ));
507 744 }
508 745 if(isset($new_prio)){
509 - $new_prio = esc_sql($new_prio);
510 - $task_new_prio = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}wppm_task_priorities where id= '$new_prio'");
746 + $new_prio = absint($new_prio);
747 + $task_new_prio = $wpdb->get_row( $wpdb->prepare(
748 + "SELECT * FROM {$wpdb->prefix}wppm_task_priorities where id = %d",
749 + $new_prio
750 + ));
511 751 }
512 752 $task_prev_prio_name = !empty($task_prev_prio) ? $task_prev_prio->name: "None";
513 753 $task_new_prio_name = !empty($task_new_prio) ? $task_new_prio->name: "None";
514 - esc_html_e("changed priority from $task_prev_prio_name to $task_new_prio_name","taskbuilder");
754 + printf(
755 + esc_html__( 'Changed priority from %1$s to %2$s', 'taskbuilder' ),
756 + esc_html( $task_prev_prio_name ),
757 + esc_html( $task_new_prio_name )
758 + );
515 759 }
516 760 ?>
517 - <small class="wppm_comment_date" style="color:<?php echo esc_attr($appearance_settings['comment-date-color']);?>"><i><?php echo esc_html($thread_date) ?></i></small>
761 + <small class="wppm_comment_date" style="color:<?php echo esc_attr($appearance_settings['comment-date-color']);?>"><i><?php echo isset($thread_date) ? esc_html($thread_date) : '' ?></i></small>
518 762 <div class="wppm_thread_action">
519 763 <?php if((((($current_user->has_cap('manage_options')) || ($wppmfunction->has_comment_permission('edit_task_comment',$id,$comment->id))) && ((empty($task_comment_meta->comment_type)) || (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='comment')))) && ($task->is_archived!=1)){ ?>
520 764 <span title="Edit this thread" onclick="wppm_edit_thread(<?php echo esc_attr($comment->id)?>,<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit1.svg'); ?>" alt="edit"></span>
521 765 <span title="Delete this thread" onclick="wppm_delete_thread(<?php echo esc_attr($comment->id) ?>,<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/trash.svg'); ?>" alt="delete"></span>
@@ -523,11 +767,16 @@
523 767 </div>
524 768 </div>
525 769 <div class="wppm_thread_messege" style="color:<?php echo esc_attr($appearance_settings['comment-secondary-color']);?>">
526 770 <?php
527 - $allowedtags = array( 'br' => array(), 'abbr' => array('title' => array(),), 'p' => array(), 'strong' => array(), 'a' => array('href' => array(), 'title' => array(), 'target'=> array(), 'rel'=>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(),));
771 + $allowedtags = array( 'br' => array(), 'abbr' => array('title' => array(),), 'p' => array(), 'strong' => array(), 'a' => array('href' => array(), 'title' => array(), 'target'=> array(), 'rel'=>array()),'em' =>array(),'span' =>array('class' => true,
772 + 'data-user-id' => true,'data-username' => true,), '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(),));
528 773 if(!empty($comment_body) && ((empty($task_comment_meta->comment_type)) || (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='comment') || (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='delete_task_comment'))){
529 - echo wp_kses(wpautop($comment_body),$allowedtags) ;
774 + $comment_body = $wppmfunction->wppm_clean_mentions_html($comment_body);
775 + $comment_body = $wppmfunction->wppm_highlight_user_mentions($comment_body, $current_user->ID);
776 + //echo wp_kses(wpautop($comment_body),$allowedtags);
777 + //wp_kses($comment, $allowed_tags);
778 + echo wp_kses_post(($comment_body));
530 779 } elseif(!empty($comment->body) && (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='change_task_status')){ ?>
531 780 <span class="wppm_admin_label" style="margin-right: 10px; background-color:<?php echo isset($task_prev_status->bg_color) ? esc_attr($task_prev_status->bg_color):""; ?>;color:<?php echo isset($task_prev_status->color) ? esc_attr($task_prev_status->color): "" ?>;"><?php echo isset($task_prev_status->name) ? esc_attr($task_prev_status->name) : "" ?></span> <img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/arrow-right.svg'); ?>" alt="arrow_right"> <span class="wppm_admin_label" style="margin-left:10px; background-color:<?php echo isset($task_new_status->bg_color) ? esc_attr($task_new_status->bg_color):""; ?>;color:<?php echo isset($task_new_status->color) ? esc_attr($task_new_status->color): "" ?>;"><?php echo isset($task_new_status->name) ? esc_attr($task_new_status->name) : "" ?></span><?php
532 781 }elseif(!empty($comment->body) && (isset($task_comment_meta->comment_type) && $task_comment_meta->comment_type=='change_task_creator')){ ?>
533 782 <span style="margin-right: 10px;"><?php echo isset($prev_user_data->display_name) ? esc_attr($prev_user_data->display_name) : "" ?></span> <img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/arrow-right.svg'); ?>" alt="arrow_right"> <span style="margin-left:10px;"><?php echo isset($new_user_data->display_name) ? esc_attr($new_user_data->display_name) : "" ?></span><?php
@@ -576,10 +825,13 @@
576 825 <?php
577 826 if(!empty($attachments)){
578 827 foreach( $attachments as $attachment ):
579 828 $download_url = site_url('/').'?wppm_attachment='.$attachment.'&tid='.$id.'&tac='.$auth_id;
580 - $attachment = esc_sql($attachment);
581 - $attach = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_attachments where id='$attachment'");
829 + $attachment = absint($attachment);
830 + if (empty($attachment)) {
831 + continue; // or return, depending on the context
832 + }
833 + $attach = $wpdb->get_row( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_attachments where id=%d",$attachment));
582 834 $findStr = ".txt";
583 835 if(!empty( $attach)){
584 836 $attachment_name = preg_replace('/' . $findStr . '/', "", $attach->name, 1);
585 837 $attachment_name = sanitize_file_name($attachment_name);
@@ -590,9 +842,9 @@
590 842 <td>
591 843 <a class="wppm_attachment_link" href="<?php echo esc_url($download_url) ?>" target="_blank">
592 844 <span class="wppm_attachment_file_name" style="padding: 7px;"><?php echo isset($attach->file_name) ? esc_html($attach->file_name):"";?></span></a>
593 845 <?php if((($comment->created_by == $current_user->ID) || ($current_user->has_cap('manage_options')) || ($wppmfunction->has_comment_permission('edit_task_comment',$id,$comment->id))) && ($task->is_archived!=1)){ ?>
594 - <span class="wppm_thread_action_btn" onclick="wppm_thread_attachment_remove(this,<?php echo esc_attr($attach->id); ?>,<?php echo esc_attr($comment->id); ?>,<?php echo esc_attr($id); ?>,<?php echo esc_attr($proj_id);?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cancel.svg'); ?>" alt="cancel"></span>
846 + <span class="wppm_thread_action_btn" onclick="wppm_thread_attachment_remove(this,<?php echo !empty($attach->id) ? esc_attr($attach->id) : 0; ?>,<?php echo !empty($comment->id) ? esc_attr($comment->id) : 0; ?>,<?php echo !empty($id) ? esc_attr($id) : 0; ?>,<?php echo !empty($proj_id) ? esc_attr($proj_id) : 0;?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/cancel.svg'); ?>" alt="cancel"></span>
595 847 <?php } ?>
596 848 </td>
597 849 </tr>
598 850 <input type="hidden" name="wppm_ajax_nonce" id="wppm_ajax_nonce" value="<?php echo esc_attr( wp_create_nonce( 'wppm_remove_thread_attachment' ) ); ?>">
@@ -613,12 +865,14 @@
613 865 <div class="row wppm_widget" id="wppm_status_widget">
614 866 <div class="wppm-widget-header" style="background-color:<?php echo esc_attr($appearance_settings['widget-header-bg-color'])?>">
615 867 <h4 class="widget_header" style="color:<?php echo esc_attr($appearance_settings['widget-header-text-color'])?>"><?php echo esc_html_e('Status','taskbuilder')?></h4>
616 868 <?php
617 - if((($current_user->has_cap('manage_options') || $wppm_current_user_capability == ('wppm_admin') || ($flag==true) || ($wppmfunction->has_permission('change_task_status',$id))!="") && ($task->is_archived!=1))){
618 - ?>
619 - <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_status(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
620 - <?php
869 + if($user_role != 3){
870 + if((($current_user->has_cap('manage_options') || $wppm_current_user_capability == ('wppm_admin') || ($flag==true) || ($wppmfunction->has_permission('change_task_status',$id))!="") && ($task->is_archived!=1))){
871 + ?>
872 + <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_status(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
873 + <?php
874 + }
621 875 }
622 876 ?>
623 877 </div>
624 878 <hr class="widget_divider">
@@ -629,11 +883,13 @@
629 883 <div class="row wppm_widget" id="wppm_raisedby_widget">
630 884 <div class="wppm-widget-header" style="background-color:<?php echo esc_attr($appearance_settings['widget-header-bg-color'])?>">
631 885 <h4 class="widget_header" style="color:<?php echo esc_attr($appearance_settings['widget-header-text-color'])?>">
632 886 <?php echo esc_html_e('Task Creator','taskbuilder')?></h4>
633 - <?php if ((($wppmfunction->has_permission('change_raised_by',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?>
634 - <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_creator(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
635 - <?php } ?>
887 + <?php if($user_role != 3){
888 + if ((($wppmfunction->has_permission('change_raised_by',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?>
889 + <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_creator(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
890 + <?php }
891 + }?>
636 892 </div>
637 893 <hr class="widget_divider"> <?php
638 894 if(isset($task->created_by)){
639 895 $user_info = get_userdata($task->created_by);
@@ -650,11 +906,14 @@
650 906 </div>
651 907 <div class="row wppm_widget" id="wppm_task_users_widget_container">
652 908 <div class="wppm-widget-header" style="background-color:<?php echo esc_attr($appearance_settings['widget-header-bg-color'])?>">
653 909 <h4 class="widget_header" style="color:<?php echo esc_attr($appearance_settings['widget-header-text-color'])?>;"><?php echo esc_html_e('Users','taskbuilder')?></h4>
654 - <?php if ((($wppmfunction->has_permission('assign_task_users',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?>
655 - <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_users(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
656 - <?php } ?>
910 + <?php
911 + if($user_role != 3){
912 + if ((($wppmfunction->has_permission('assign_task_users',$id ) || $current_user->has_cap('manage_options')) && ($task->is_archived!=1))) { ?>
913 + <span class="wppm_edit_task_details_widget" onclick="wppm_edit_task_users(<?php echo esc_attr($id) ?>,<?php echo esc_attr($proj_id) ?>,<?php echo esc_attr($project_id) ?>)"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/edit_01.svg'); ?>" alt="edit"></span>
914 + <?php }
915 + }?>
657 916 </div>
658 917 <hr class="widget_divider">
659 918 <div class="wppm-widget-body" style="background-color:<?php echo esc_attr($appearance_settings['widget-body-bg-color'])?>">
660 919 <div id="wppm_task_users">
@@ -685,9 +944,9 @@
685 944 </div>
686 945 </div>
687 946 <?php do_action('wppm_after_task_widgets',$id,$task_id );?>
688 947 </div>
689 - <input type="hidden" id="wppm_nonce" value="<?php echo wp_create_nonce('wppm_upload_file')?>">
948 + <input type="hidden" id="wppm_nonce" value="<?php echo esc_attr(wp_create_nonce('wppm_upload_file'))?>">
690 949 <input type="file" id="wppm_attachment_upload" class="hidden" onchange="">
691 950 </div>
692 951 </form>
693 952 <style>
@@ -717,8 +976,11 @@
717 976 // Hide when clicking outside
718 977 document.addEventListener('click', () => {
719 978 box.style.display = 'none';
720 979 });
980 + jQuery('#wppm_task_comment').on('focus', function(){
981 + // showMentionList('');
982 + });
721 983 <?php
722 984 if ((($current_user->ID && $current_user->has_cap('manage_options')) || $wppmfunction->has_permission('change_task_details',$task->id))){ ?>
723 985 jQuery("#wppm_edit_tstart_date").flatpickr({
724 986 enableTime: true,
@@ -763,9 +1025,9 @@
763 1025 jQuery('#CheckProgress_'+<?php echo esc_attr($chklist->id);?>).css('width', progressWidth + '%');
764 1026 if(progressWidth>0){
765 1027 jQuery('#wppm_progressbar_label_'+<?php echo esc_attr($chklist->id);?>).text(progressWidth+'%');
766 1028 }
767 - <?php $wppm_checklist_items = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_checklist_items where checklist_id=".$chklist->id);
1029 + <?php $wppm_checklist_items = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$wpdb->prefix}wppm_checklist_items where checklist_id=%d",$chklist->id));
768 1030 foreach ($wppm_checklist_items as $chkitems) {
769 1031 ?> jQuery( '#wppm_checklist_'+<?php echo esc_attr($chkitems->id);?>).on("mouseover", function () {
770 1032 jQuery( '#wppm_checklist_action_'+<?php echo esc_attr($chkitems->id);?>).css("display","inline");
771 1033 jQuery( '#wppm_checklist_'+<?php echo esc_attr($chkitems->id);?>).css("background-color","#e7e8ea");
@@ -781,47 +1043,59 @@
781 1043 $italic = (isset($wppm_toolbar_actions['italic']) && $wppm_toolbar_actions['italic']==1)? 'italic' :"";
782 1044 $underline = (isset($wppm_toolbar_actions['underline']) && $wppm_toolbar_actions['underline']==1)?'underline' :"";
783 1045 $blockquote = (isset($wppm_toolbar_actions['blockquote']) && $wppm_toolbar_actions['blockquote']==1)? 'blockquote' :"";
784 1046 $align = (isset($wppm_toolbar_actions['align']) && $wppm_toolbar_actions['align']==1)? ' alignleft aligncenter alignright ' :"";
785 - $bullist = (isset($wppm_toolbar_actions['bullist']) && $wppm_toolbar_actions['bullist']==1)? $bullist = 'bullist' :"";
786 - $numlist = (isset($wppm_toolbar_actions['numlist']) && $wppm_toolbar_actions['numlist']==1)? $numlist = 'numlist' :"";
787 - $rtl = (isset($wppm_toolbar_actions['rtl']) && $wppm_toolbar_actions['rtl']==1)? $rtl = 'rtl' :"";
788 - $link = (isset($wppm_toolbar_actions['link']) && $wppm_toolbar_actions['link']==1)? $link = 'link' :"";
789 - $image = (isset($wppm_toolbar_actions['wppm_insert_editor_img']) && $wppm_toolbar_actions['wppm_insert_editor_img']==1)? $image = 'image' :"";
790 - $forecolor = (isset($wppm_toolbar_actions['forecolor']) && $wppm_toolbar_actions['forecolor']==1)? $forecolor = 'forecolor' :"";
791 - $backcolor = (isset($wppm_toolbar_actions['backcolor']) && $wppm_toolbar_actions['backcolor']==1)? $backcolor = 'backcolor' :"";
792 - $strikethrough = (isset($wppm_toolbar_actions['strikethrough']) && $wppm_toolbar_actions['strikethrough']==1)? $strikethrough = 'strikethrough' :"";
793 - if(($wppm_tinymce_visibility_open_task==1)){
794 - if(!empty($wppm_rich_text_editor) && ($wppm_rich_text_editor == 1)){
795 - ?>
796 - tinymce.remove();
797 - tinymce.init({
1047 + $bullist = (isset($wppm_toolbar_actions['bullist']) && $wppm_toolbar_actions['bullist']==1)? 'bullist' :"";
1048 + $numlist = (isset($wppm_toolbar_actions['numlist']) && $wppm_toolbar_actions['numlist']==1)? 'numlist' :"";
1049 + $rtl = (isset($wppm_toolbar_actions['rtl']) && $wppm_toolbar_actions['rtl']==1)? 'rtl' :"";
1050 + $link = (isset($wppm_toolbar_actions['link']) && $wppm_toolbar_actions['link']==1)? 'link' :"";
1051 + $image = (isset($wppm_toolbar_actions['wppm_insert_editor_img']) && $wppm_toolbar_actions['wppm_insert_editor_img']==1)? 'image' :"";
1052 + $forecolor = (isset($wppm_toolbar_actions['forecolor']) && $wppm_toolbar_actions['forecolor']==1)? 'forecolor' :"";
1053 + $backcolor = (isset($wppm_toolbar_actions['backcolor']) && $wppm_toolbar_actions['backcolor']==1)? 'backcolor' :"";
1054 + $strikethrough = (isset($wppm_toolbar_actions['strikethrough']) && $wppm_toolbar_actions['strikethrough']==1)? 'strikethrough' :"";
1055 + $toolbar = trim("$bold $italic $underline $blockquote | $align | $bullist $numlist | $rtl | $link $image | $forecolor $backcolor $strikethrough");
1056 + if(($wppm_tinymce_visibility_open_task==1)){ ?>
1057 + if((wppm_admin.rich_text_editor) && (wppm_admin.rich_text_editor.trim().length > 0) && (wppm_admin.rich_text_editor == 1)){
1058 + getMentionDropdown(editor);
1059 + tinymce.remove();
1060 + tinymce.init({
798 1061 selector:'#wppm_task_comment',
799 1062 body_id: 'wppm_task_comment',
800 - directionality : '<?php //echo 'rtl'; ?>',
801 1063 menubar: false,
802 1064 statusbar: false,
803 1065 height : '200',
804 1066 width : '100%',
805 - plugins: [
806 - 'lists link image directionality paste textcolor'
807 - ],
808 - image_advtab: true,
809 - toolbar: '<?php echo $bold ?> <?php echo $italic ?> <?php echo $underline ?> <?php echo $blockquote?> | <?php echo $align ?> | <?php echo $bullist ?> <?php echo $numlist ?> | <?php echo $rtl ?> | <?php echo $link ?> <?php echo $image ?> | <?php echo $forecolor?> <?php echo $backcolor?> <?php echo $strikethrough ?>',
810 - branding: false,
811 - autoresize_bottom_margin: 20,
812 - browser_spellcheck : true,
813 - relative_urls : false,
814 - remove_script_host : false,
815 - convert_urls : true,
816 - paste_as_text: true,
1067 + plugins: ['lists link image directionality paste textcolor'],
1068 + valid_elements: '*[*]',
1069 + extended_valid_elements: 'span[class|data-username|data-user-id|,p,br,strong,em,a[href|target]contenteditable]',
1070 + toolbar:'<?php echo esc_js($toolbar); ?>',
1071 + content_style: `
1072 + .wppm-mention{
1073 + display:inline-block;
1074 + background:linear-gradient(135deg,#eef2ff,#e0e7ff);
1075 + color:#5b21b6;
1076 + padding:2px 8px;
1077 + border-radius:16px;
1078 + font-weight:600;
1079 + border:1px solid #c7d2fe;
1080 + }
1081 +
1082 + .wppm-mention-me{
1083 + background:linear-gradient(135deg,#fef3c7,#fde68a);
1084 + color:#92400e;
1085 + border:1px solid #fbbf24;
1086 + font-weight:700;
1087 + }
1088 + `
817 1089 setup: function (editor) {
1090 + wppmmenwppmMentionSetup(editor)
1091 +
1092 + } // ✅ only ONE setup
1093 + });
1094 + jQuery('#wppm_comment_btn').show();
818 1095 }
819 - });
820 - jQuery('#wppm_comment_btn').show();
821 - <?php } ?>
822 - <?php } ?>
823 -});
1096 + <?php } ?>
1097 + });
824 1098
825 1099 jQuery(function(jQuery){
826 1100 // Checklist Sorting
827 1101 jQuery(".wppm_checklist_items_container").sortable({
@@ -873,54 +1147,64 @@
873 1147 <?php }?>
874 1148 }
875 1149
876 1150 function wppm_add_task_comment(){
877 - <?php
878 - if(!empty($wppm_rich_text_editor) && ($wppm_rich_text_editor == 1)){
879 - ?>
880 - tinymce.remove();
881 - tinymce.init({
882 - selector:'#wppm_task_comment',
883 - body_id: 'wppm_task_comment',
884 - directionality : '<?php //echo 'rtl'; ?>',
885 - menubar: false,
886 - statusbar: false,
887 - height : '200',
888 - width : '100%',
889 - plugins: [
890 - 'lists link image directionality paste textcolor'
891 - ],
892 - image_advtab: true,
893 - toolbar: '<?php echo $bold ?> <?php echo $italic ?> <?php echo $underline ?> <?php echo $blockquote?> | <?php echo $align ?> | <?php echo $bullist ?> <?php echo $numlist ?> | <?php echo $rtl ?> | <?php echo $link ?> <?php echo $image ?> | <?php echo $forecolor?> <?php echo $backcolor?> <?php echo $strikethrough ?>',
894 - branding: false,
895 - autoresize_bottom_margin: 20,
896 - browser_spellcheck : true,
897 - relative_urls : false,
898 - remove_script_host : false,
899 - convert_urls : true,
900 - paste_as_text: true,
901 - setup: function (editor) {
902 - }
903 - });
904 - <?php } else{ ?>
1151 + if((wppm_admin.rich_text_editor == 1)){
1152 + tinymce.remove();
1153 + tinymce.init({
1154 + selector:'#wppm_task_comment',
1155 + body_id: 'wppm_task_comment',
1156 + directionality : '<?php //echo 'rtl'; ?>',
1157 + menubar: false,
1158 + statusbar: false,
1159 + height : '200',
1160 + width : '100%',
1161 + plugins: [
1162 + 'lists link image directionality paste textcolor'
1163 + ],
1164 + image_advtab: true,
1165 + toolbar:'<?php echo esc_js( $toolbar ); ?>',
1166 + branding: false,
1167 + autoresize_bottom_margin: 20,
1168 + browser_spellcheck : true,
1169 + relative_urls : false,
1170 + remove_script_host : false,
1171 + convert_urls : true,
1172 + paste_as_text: true,
1173 + setup: function (editor) {
1174 + wppmMentionSetup(editor);
1175 + }
1176 + });
1177 + } else{
905 1178 jQuery('#wppm_task_comment').css("width", "100%");
906 1179 jQuery('#wppm_task_comment').css("height", "160px");
907 1180 jQuery('#wppm_task_comment').css("color", "#000");
908 - <?php }?>
1181 + }
909 1182 jQuery('#wppm_comment_btn').show();
910 1183 }
911 1184
912 -function wppm_submit_task_comment(id,proj_id){
1185 +function wppm_submit_task_comment(id, proj_id){
1186 + jQuery('#wppm_mention_list').remove();
913 1187 var dataform = new FormData(jQuery('#wppm_open_task')[0]);
914 1188 dataform.append('action','wppm_submit_task_comment');
915 - <?php
916 - if(!empty($wppm_rich_text_editor) && ($wppm_rich_text_editor == 1)){ ?>
917 - var comment_body = tinyMCE.get('wppm_task_comment').getContent().trim();
918 - <?php } else{ ?>
919 - var comment_body = jQuery("#wppm_task_comment").val();
920 - <?php }?>
921 - dataform.append('comment_body',comment_body);
922 - dataform.append('task_id',id);
1189 + let comment_body;
1190 + if(wppm_admin.rich_text_editor == 1){
1191 + const editor = tinyMCE.get('wppm_task_comment');
1192 + // Remove dropdown from TinyMCE iframe
1193 + const dropdown = editor.getDoc().getElementById('wppm_mention_list');
1194 + if (dropdown) {
1195 + dropdown.remove();
1196 + }
1197 + comment_body = editor.getContent().trim();
1198 + //comment_body = tinyMCE.get('wppm_task_comment').getContent().trim();
1199 + // remove mention dropdown if accidentally inserted
1200 + //comment_body = comment_body.replace(/<div[^>]*id="wppm_mention_list"[^>]*>.*?<\/div>/gi, '');
1201 + comment_body = comment_body.replace( /<div class="mention-item"[\s\S]*?<\/div>/g, '');
1202 + } else {
1203 + comment_body = jQuery("#wppm_task_comment").val();
1204 + }
1205 + dataform.append('comment_body', comment_body);
1206 + dataform.append('task_id', id);
923 1207 jQuery('#wppm_task_container').html(wppm_admin.loading_html);
924 1208 jQuery.ajax({
925 1209 url: wppm_admin.ajax_url,
926 1210 type: 'POST',
@@ -927,12 +1211,12 @@
927 1211 data: dataform,
928 1212 processData: false,
929 1213 contentType: false
930 1214 })
931 - .done(function (response_str) {
932 - if((proj_id!=0)||(proj_id!="")){
933 - wppm_open_project_tasks(id,proj_id);
934 - }else if((proj_id==0)||(proj_id=="")){
1215 + .done(function () {
1216 + if (proj_id != 0 && proj_id != "") {
1217 + wppm_open_project_tasks(id, proj_id);
1218 + } else {
935 1219 wppm_open_task(id);
936 1220 }
937 1221 });
938 1222 }
@@ -971,9 +1255,10 @@
971 1255 var file_extension = file_name_split[file_name_split.length-1];
972 1256 file_extension = file_extension.toLowerCase();
973 1257 if( (jQuery.inArray(file_extension,allowedExtension) > -1)){
974 1258 flag = true;
975 - alert("<?php _e('Attached file type not allowed!','taskbuilder')?>");
1259 + alert("<?php echo esc_js(__( 'Attached file type not allowed!', 'taskbuilder' ) ); ?>");
1260 +
976 1261 };
977 1262 <?php
978 1263 $max_upload = (int)(ini_get('upload_max_filesize')); ?>
979 1264 var current_filesize=file.size/1000000;
@@ -978,9 +1263,9 @@
978 1263 $max_upload = (int)(ini_get('upload_max_filesize')); ?>
979 1264 var current_filesize=file.size/1000000;
980 1265 if(current_filesize > <?php echo esc_attr($max_upload); ?>){
981 1266 flag = true;
982 - alert("<?php _e('File size exceed allowed limit!','taskbuilder')?>");
1267 + alert("<?php echo esc_js(__('File size exceed allowed limit!','taskbuilder')); ?>");
983 1268 }
984 1269 if (!flag){
985 1270 var html_str = '<div class="wppm_attachment">'+
986 1271 '<div class="progress" style="float: none !important; width: unset !important;">'+
@@ -1027,6 +1312,227 @@
1027 1312 });
1028 1313 }
1029 1314 });
1030 1315 jQuery('#wppm_attachment_upload').trigger('click');
1316 +}
1317 +
1318 +function wppmMentionSetup(editor) {
1319 + let mentionIndex = -1;
1320 + editor.on('keyup', function (e) {
1321 + editor.lastMentionRange = editor.selection.getRng();
1322 + let rng = editor.selection.getRng();
1323 + let node = rng.startContainer;
1324 +
1325 + if (!node || node.nodeType !== 3) return;
1326 +
1327 + let text = node.textContent;
1328 + let cursorPos = rng.startOffset;
1329 + let textBeforeCursor = text.substring(0, cursorPos);
1330 +
1331 + let match = textBeforeCursor.match(/@(\w*)$/);
1332 + let dropdown = getMentionDropdown(editor);
1333 +
1334 + if (match) {
1335 + let query = match[1];
1336 + let rect = rng.getBoundingClientRect();
1337 + if (!rect || rect.top === 0) {
1338 + rect = editor.selection.getNode().getBoundingClientRect();
1339 + }
1340 + let top = rect.bottom + editor.getWin().scrollY;
1341 + let left = rect.left + editor.getWin().scrollX;
1342 + jQuery.post(wppm_admin.ajax_url, {
1343 + action: 'wppm_filter_autocomplete',
1344 + term: query,
1345 + field : 'task_user_name',
1346 + task_id:<?php echo esc_attr($task_id) ?>,
1347 + proj_id:<?php echo esc_attr($proj_id) ?>
1348 + }, function (res) {
1349 +
1350 + if (typeof res === "string") res = JSON.parse(res);
1351 + if (res.success) res = res.data;
1352 +
1353 + if (!Array.isArray(res)) return;
1354 +
1355 + dropdown.empty();
1356 + if( res.length === 0 ){
1357 + dropdown.hide();
1358 + return;
1359 + }else{
1360 + res.forEach(user => {
1361 + let item = jQuery('<div>')
1362 + .addClass('mention-item')
1363 + .attr('data-username', user.label)
1364 + .attr('data-user-id', user.user_id)
1365 + .text(user.label)
1366 + .css({
1367 + padding: '8px 12px',
1368 + cursor: 'pointer',
1369 + fontSize: '14px',
1370 + color: '#333',
1371 + background: '#fff',
1372 + borderBottom: '1px solid #eee'
1373 + });
1374 +
1375 + item.on('mouseenter', function () {
1376 + jQuery(this).css({
1377 + background: '#0073aa',
1378 + color: '#fff'
1379 + });
1380 + });
1381 + item.on('mouseleave', function () {
1382 + if (!jQuery(this).hasClass('active')) {
1383 + jQuery(this).css({
1384 + background: '#fff',
1385 + color: '#333'
1386 + });
1387 + }
1388 + });
1389 + dropdown.append(item);
1390 + });
1391 + let items = dropdown.find('.mention-item');
1392 + items.removeClass('active').css({
1393 + background: '#fff',
1394 + color: '#333'
1395 + });
1396 + items.eq(0)
1397 + .addClass('active')
1398 + .css({
1399 + background: '#0073aa',
1400 + color: '#fff'
1401 + });
1402 + mentionIndex = 0;
1403 + updateActiveItem(items.eq(0), mentionIndex);
1404 + dropdown.css({
1405 + position: 'absolute',
1406 + display: 'none',
1407 + background: '#fff',
1408 + border: '1px solid #ddd',
1409 + borderRadius: '6px',
1410 + padding: '5px 0',
1411 + minWidth: '180px',
1412 + maxHeight: '220px',
1413 + overflowY: 'auto',
1414 + boxShadow: '0 4px 10px rgba(0,0,0,.15)',
1415 + zIndex: 999999999999999
1416 + }).show();
1417 + }
1418 + });
1419 + } else {
1420 + dropdown.hide();
1421 + }
1422 + });
1423 + editor.on('keydown', function (e) {
1424 + let dropdown = getMentionDropdown(editor);
1425 + let items = dropdown.find('.mention-item');
1426 +
1427 + if (!dropdown.is(':visible') || !items.length) return;
1428 +
1429 + // DOWN
1430 + if (e.key === 'ArrowDown') {
1431 + e.preventDefault();
1432 + mentionIndex++;
1433 +
1434 + if (mentionIndex >= items.length) {
1435 + mentionIndex = 0;
1436 + }
1437 + updateActiveItem(items, mentionIndex);
1438 + items.removeClass('active').css({
1439 + background: '#fff',
1440 + color: '#333'
1441 + });
1442 +
1443 + items.eq(mentionIndex)
1444 + .addClass('active')
1445 + .css({
1446 + background: '#0073aa',
1447 + color: '#fff'
1448 + });
1449 + }
1450 +
1451 + // UP
1452 + if (e.key === 'ArrowUp') {
1453 + e.preventDefault();
1454 + mentionIndex--;
1455 + if (mentionIndex < 0) {
1456 + mentionIndex = items.length - 1;
1457 + }
1458 + updateActiveItem(items, mentionIndex);
1459 + items.removeClass('active').css({
1460 + background: '#fff',
1461 + color: '#333'
1462 + });
1463 +
1464 + items.eq(mentionIndex)
1465 + .addClass('active')
1466 + .css({
1467 + background: '#0073aa',
1468 + color: '#fff'
1469 + });
1470 + }
1471 + // ENTER
1472 + if (e.key === 'Enter') {
1473 + if (mentionIndex >= 0) {
1474 + e.preventDefault();
1475 + items.eq(mentionIndex).trigger('click');
1476 + }
1477 + }
1478 + // ESC
1479 + if (e.key === 'Escape') {
1480 + dropdown.hide();
1481 + mentionIndex = -1;
1482 + }
1483 + });
1484 + editor.on('click', function (e) {
1485 + let target = jQuery(e.target);
1486 + if (target.hasClass('mention-item')) {
1487 + let username = target.data('username');
1488 + let userId = target.data('user-id');
1489 +
1490 + editor.focus();
1491 +
1492 + let rng = editor.lastMentionRange || editor.selection.getRng();
1493 + editor.selection.setRng(rng);
1494 +
1495 + let node = rng.startContainer;
1496 + if (!node || node.nodeType !== 3) return;
1497 +
1498 + let text = node.textContent;
1499 + let cursorPos = rng.startOffset;
1500 +
1501 + let lastAtIndex = text.substring(0, cursorPos).lastIndexOf('@');
1502 +
1503 + if (lastAtIndex !== -1) {
1504 +
1505 + let range = editor.selection.getRng();
1506 + range.setStart(node, lastAtIndex);
1507 + range.setEnd(node, cursorPos);
1508 +
1509 + editor.selection.setRng(range);
1510 +
1511 + editor.selection.setContent(
1512 + '<span class="wppm-mention" contenteditable="false" data-username="' + username + '" data-user-id="' + userId + '">@' + username + '</span>&nbsp;'
1513 + );
1514 + }
1515 + getMentionDropdown(editor).hide();
1516 + }
1517 + });
1518 +
1519 + editor.on('blur', function () {
1520 + getMentionDropdown(editor).hide();
1521 + });
1522 +
1523 + editor.on('init', function () {
1524 + let body = editor.getBody();
1525 + if (!body) return;
1526 +
1527 + body.addEventListener('mousedown', function (e) {
1528 + if (e.target.classList.contains('mention-item')) {
1529 + e.preventDefault();
1530 + }
1531 + });
1532 + if (!editor.mentionDropdown) {
1533 + editor.mentionDropdown = jQuery('<div class="mention-dropdown"></div>');
1534 + jQuery('body').append(editor.mentionDropdown); // ✅ ONLY HERE
1535 + }
1536 + });
1031 1537 }
1032 1538 </script>