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/projects/projects_list.php +332 -58 5.0.36.0.6 View file →
@@ -4,19 +4,66 @@
4 4 }
5 5 global $wpdb,$wppmfunction,$current_user;
6 6 $status = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_project_statuses" );
7 7 $categories = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_project_categories" );
8 -$appearance_settings = get_option("wppm-ap-project-list");
8 +$pb_users = get_users(array(
9 + 'orderby' => 'display_name',
10 + 'order' => 'ASC'
11 +));
12 +$assigned_project_users = $wpdb->get_col( "SELECT DISTINCT users FROM {$wpdb->prefix}wppm_project WHERE users != ''" );
13 +$all_assigned_proj_users = array();
14 +foreach ( $assigned_project_users as $row ) {
15 + foreach ( explode( ',', $row ) as $uid ) {
16 + $uid = trim( $uid );
17 + if ( $uid !== '' ) {
18 + $all_assigned_proj_users[] = $uid;
19 + }
20 + }
21 +}
22 +$all_assigned_proj_users = array_unique( $all_assigned_proj_users );
23 +$appearance_settings = wp_parse_args(
24 + get_option( "wppm-ap-project-list", array() ),
25 + array(
26 + 'list-header-button-background-color' => '#0052CC',
27 + 'list-header-button-hover-color' => '#0065ff',
28 + 'list-header-button-text-color' => '#fff',
29 + )
30 +);
9 31 $wppm_date_setting = get_option('wppm_date_setting');
10 32 $wppm_deafault_time_duration_project = get_option('wppm_display_time_duration_project');
11 33 $wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true );
12 34 $proj_per_page = 20;
13 35 $page_no = (isset($_POST['page_no'])) ? intval(sanitize_text_field($_POST['page_no'])): '0';
36 +$page = isset($_POST['page']) ? sanitize_text_field(wp_unslash($_POST['page'])):"";
14 37 $search_tag = isset($_POST['project_search']) ? sanitize_text_field($_POST['project_search']) : '';
15 38 $order = isset($_POST['order']) ? sanitize_text_field($_POST['order']) :"ASC";
16 39 $sort_by = isset($_POST['sort_by']) ? sanitize_text_field($_POST['sort_by']):"project_name";
17 40 $filter_by = isset($_POST['wppm_project_filter']) ? sanitize_text_field($_POST['wppm_project_filter']) : "all";
18 -$current_date = date('Y-m-d');
41 +$is_archieved = !empty($_POST['is_archieved']) ? 1 : 0;
42 +if ( isset( $_POST['filters'] ) ) {
43 + if ( is_string( $_POST['filters'] ) ) {
44 + $advanced_filter = json_decode( stripslashes( sanitize_text_field( wp_unslash( $_POST['filters'] ) ) ), true );
45 + } elseif ( is_array( $_POST['filters'] ) ) {
46 + $raw_filters = wp_unslash( $_POST['filters'] );
47 + $advanced_filter = array(
48 + 'created_by' => array_map( 'absint', (array) ( $raw_filters['created_by'] ?? array() ) ),
49 + 'assigned' => array_map( 'absint', (array) ( $raw_filters['assigned'] ?? array() ) ),
50 + 'category' => array_map( 'absint', (array) ( $raw_filters['category'] ?? array() ) ),
51 + 'start_date' => sanitize_text_field( $raw_filters['start_date'] ?? '' ),
52 + 'end_date' => sanitize_text_field( $raw_filters['end_date'] ?? '' ),
53 + );
54 + } else {
55 + $advanced_filter = array();
56 + }
57 +} elseif ( ! empty( $_COOKIE['tb_proj_list_filters'] ) ) {
58 + $advanced_filter = json_decode( stripslashes( sanitize_text_field( wp_unslash( $_COOKIE['tb_proj_list_filters'] ) ) ), true );
59 +} else {
60 + $advanced_filter = array();
61 +}
62 +if ( ! is_array( $advanced_filter ) ) {
63 + $advanced_filter = array();
64 +}
65 +$current_date = wp_date('Y-m-d');
19 66 $wppm_pl_filter = "1=1";
20 67 $wppm_hide_completed_status_proj = get_option('wppm_hide_completed_status_proj');
21 68 $cu_id = esc_sql($current_user->ID);
22 69 $wppm_hide_proj_statuses_from_frontend = get_option('wppm_hide_proj_statuses_from_frontend');
@@ -24,8 +71,9 @@
24 71 $wppm_hide_proj_statuses_from_frontend = explode(",",$wppm_hide_proj_statuses_from_frontend);
25 72 } else {
26 73 $wppm_hide_proj_statuses_from_frontend = '';
27 74 }
75 +$is_admin = ( $wppm_current_user_capability === 'wppm_admin' || current_user_can('manage_options') ) ? 1 : 0;
28 76 $filters = array(
29 77 'sort_by' => $sort_by,
30 78 'order' => $order,
31 79 'search' => $search_tag,
@@ -88,8 +136,11 @@
88 136 }elseif($filter_by == '3'){
89 137 $wppm_pl_filter = "status='3'";
90 138 }elseif($filter_by == 'mine'){
91 139 $wppm_pl_filter = "(FIND_IN_SET('$current_user->ID',users)>0)";
140 +}elseif($filter_by == 'active'){
141 + $wppm_pl_filter = " (FIND_IN_SET('$current_user->ID', users) OR created_by = '$current_user->ID' OR $is_admin = 1 )
142 + AND status != 4";
92 143 }
93 144
94 145 if(!empty($wppm_hide_proj_statuses_from_frontend) && is_array($wppm_hide_proj_statuses_from_frontend) && ((isset($_POST['is_frontend'])) && (sanitize_text_field($_POST['is_frontend'])==1))){
95 146 foreach($wppm_hide_proj_statuses_from_frontend as $status){
@@ -95,46 +146,115 @@
95 146 foreach($wppm_hide_proj_statuses_from_frontend as $status){
96 147 $wppm_pl_filter .= " AND status != '$status'";
97 148 }
98 149 }
99 -
150 +$advanced_conditions = array();
151 +if ( ! empty( $advanced_filter['created_by'] ) ) {
152 + $created_by_ids = array_map( 'intval', (array) $advanced_filter['created_by'] );
153 + $advanced_conditions[] = "created_by IN (" . implode( ',', $created_by_ids ) . ")";
154 +}
155 +if ( ! empty( $advanced_filter['assigned'] ) ) {
156 + $assigned_ids = array_map( 'intval', (array) $advanced_filter['assigned'] );
157 + $assigned_sql = array();
158 + foreach ( $assigned_ids as $id ) {
159 + $assigned_sql[] = "FIND_IN_SET('$id', users)";
160 + }
161 + $advanced_conditions[] = "(" . implode( ' OR ', $assigned_sql ) . ")";
162 +}
163 +if ( ! empty( $advanced_filter['category'] ) ) {
164 + $category_ids = array_map( 'intval', (array) $advanced_filter['category'] );
165 + $advanced_conditions[] = "cat_id IN (" . implode( ',', $category_ids ) . ")";
166 +}
167 +if ( ! empty( $advanced_filter['start_date'] ) && preg_match( '/^\d{4}-\d{2}-\d{2}$/', $advanced_filter['start_date'] ) ) {
168 + $advanced_conditions[] = $wpdb->prepare( "(CAST(start_date AS DATE)) >= %s", $advanced_filter['start_date'] );
169 +}
170 +if ( ! empty( $advanced_filter['end_date'] ) && preg_match( '/^\d{4}-\d{2}-\d{2}$/', $advanced_filter['end_date'] ) ) {
171 + $advanced_conditions[] = $wpdb->prepare( "(CAST(end_date AS DATE)) <= %s", $advanced_filter['end_date'] );
172 +}
173 +if ( ! empty( $advanced_conditions ) ) {
174 + $wppm_pl_filter .= " AND " . implode( " AND ", $advanced_conditions );
175 +}
100 176 $wppm_project_time = get_option('wppm_project_time');
101 177 $wppm_default_project_date = get_option('wppm_default_project_date');
102 178 $sort_by = apply_filters('wppm_project_list_sort_by_query',$sort_by);
103 179 $order = apply_filters('wppm_project_list_order_query',$order);
104 180 $search_tag_text = '%'.$wpdb->esc_like($search_tag).'%';
105 -if(!empty($search_tag)){
106 - $search_tag_text = '%'.$wpdb->esc_like($search_tag).'%';
107 - $query = ("SELECT Project.*
108 - FROM {$wpdb->prefix}wppm_project AS Project
109 - Left join {$wpdb->prefix}wppm_project_statuses proj_statuses ON Project.status = proj_statuses.id
110 - Left join {$wpdb->prefix}wppm_project_categories proj_categories ON Project.cat_id = proj_categories.id
111 - Left join {$wpdb->base_prefix}users user ON (FIND_IN_SET(user.ID,Project.users)>0) AND (user.display_name LIKE '$search_tag_text')
112 - Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id
113 - ");
114 - if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
115 - $where = " where $wppm_pl_filter AND (Project.project_name LIKE '$search_tag_text' OR proj_statuses.name LIKE '$search_tag_text' OR proj_categories.name LIKE '$search_tag_text' OR ( user.display_name LIKE '$search_tag_text'))";
116 - }else{
117 - $where = " where $wppm_pl_filter AND (Project.project_name LIKE '$search_tag_text' OR proj_statuses.name LIKE '$search_tag_text' OR proj_categories.name LIKE '$search_tag_text' OR ( user.display_name LIKE '$search_tag_text')) AND ((FIND_IN_SET('$current_user->ID',Project.users)>0) OR (Project.id = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) OR Project.created_by='$cu_id')";
118 - }
119 -}else{
120 - if($sort_by=='project_name'|| $sort_by=='start_date' || $sort_by=='end_date'){
121 - $query = ( "SELECT Project.* FROM {$wpdb->prefix}wppm_project AS Project
122 - Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id
123 - ");
124 - } else{
125 - $query = ( "SELECT Project.* FROM {$wpdb->prefix}wppm_project AS Project
126 - Left join {$wpdb->prefix}wppm_project_statuses proj_statuses ON Project.status = proj_statuses.id
127 - Left join {$wpdb->prefix}wppm_project_categories proj_categories ON Project.cat_id = proj_categories.id
128 - Left join {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id
129 - ");
130 - }
131 - if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
132 - $where = " where $wppm_pl_filter";
133 - }else{
134 - $where = " where ($wppm_pl_filter AND (FIND_IN_SET('$current_user->ID',Project.users)>0 OR (Project.id = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1)) OR Project.created_by='$cu_id')";
135 - }
181 +if (!empty($search_tag)) {
182 + $search_tag_text = '%' . $wpdb->esc_like($search_tag) . '%';
183 + $query = "SELECT Project.*
184 + FROM {$wpdb->prefix}wppm_project AS Project
185 + LEFT JOIN {$wpdb->prefix}wppm_project_statuses proj_statuses ON Project.status = proj_statuses.id
186 + LEFT JOIN {$wpdb->prefix}wppm_project_categories proj_categories ON Project.cat_id = proj_categories.id
187 + LEFT JOIN {$wpdb->base_prefix}users user ON FIND_IN_SET(user.ID, Project.users) > 0
188 + LEFT JOIN {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id";
189 + // SAFE search condition
190 + $search_sql = $wpdb->prepare(
191 + "(Project.project_name LIKE %s
192 + OR proj_statuses.name LIKE %s
193 + OR proj_categories.name LIKE %s
194 + OR user.display_name LIKE %s)",
195 + $search_tag_text,
196 + $search_tag_text,
197 + $search_tag_text,
198 + $search_tag_text
199 + );
200 + if ($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') {
201 + // ✅ Admin (safe)
202 + $where = " WHERE $wppm_pl_filter AND $search_sql";
203 + } else {
204 + // ✅ Non-admin (safe)
205 + $where = $wpdb->prepare(
206 + " WHERE $wppm_pl_filter
207 + AND $search_sql
208 + AND (
209 + FIND_IN_SET(%d, Project.users) > 0
210 + OR (
211 + proj_meta.meta_key = 'public_project'
212 + AND proj_meta.meta_value = 1
213 + )
214 + OR Project.created_by = %d
215 + )",
216 + $current_user->ID,
217 + $cu_id
218 + );
219 + }
220 +} else {
221 + if ($sort_by == 'project_name' || $sort_by == 'start_date' || $sort_by == 'end_date') {
222 + $query = "SELECT Project.*
223 + FROM {$wpdb->prefix}wppm_project AS Project
224 + LEFT JOIN {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id";
225 + } else {
226 + $query = "SELECT Project.*
227 + FROM {$wpdb->prefix}wppm_project AS Project
228 + LEFT JOIN {$wpdb->prefix}wppm_project_statuses proj_statuses ON Project.status = proj_statuses.id
229 + LEFT JOIN {$wpdb->prefix}wppm_project_categories proj_categories ON Project.cat_id = proj_categories.id
230 + LEFT JOIN {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id";
231 + }
232 + if ($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') {
233 + $where = " WHERE $wppm_pl_filter";
234 + } else {
235 + $where = $wpdb->prepare(
236 + " WHERE $wppm_pl_filter
237 + AND (
238 + FIND_IN_SET(%d, Project.users) > 0
239 + OR (
240 + proj_meta.meta_key = 'public_project'
241 + AND proj_meta.meta_value = 1
242 + )
243 + OR Project.created_by = %d
244 + )",
245 + $current_user->ID,
246 + $cu_id
247 + );
248 + }
136 249 }
250 +$archived_where = '';
251 +if ( isset( $is_archieved ) && $is_archieved === 1 ) {
252 + $archived_where = ' AND Project.is_archived = 1';
253 +} else {
254 + $archived_where = ' AND Project.is_archived = 0';
255 +}
256 +$where .= $archived_where;
137 257 $no_of_rows = ( "SELECT count(*) FROM ($query");
138 258 $no_of_rows = apply_filters('wppm_project_list_no_of_rows',$no_of_rows,$wppm_pl_filter,$search_tag);
139 259 $where = apply_filters('wppm_project_list_query_where',$where, $wppm_pl_filter,$search_tag);
140 260 $query .= $where." Group by Project.id ORDER BY $sort_by $order";
@@ -159,13 +279,17 @@
159 279 <div id="wppm_project_list_container" class="wppm_bootstrap">
160 280 <div class="row">
161 281 <div class="col-sm-12" id="wppm_heading_inline">
162 282 <span class="wppm-heading-inline">
163 - <?php echo esc_html_e('Projects','taskbuilder');?>
283 + <?php echo !empty($is_archieved) ? esc_html__('Archived Projects', 'taskbuilder') : esc_html__('Projects', 'taskbuilder'); ?>
164 284 </span>
165 - <?php if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_manager'|| $wppm_current_user_capability == 'wppm_admin' ){ ?>
166 - <img width="25" height="30" id="wppm_add_new_project_btn" class="wppm_add_new_project_btn" onclick="wppm_add_new_project()" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/add.svg'); ?>" alt="add">
167 - <?php } ?>
285 + <?php if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_manager'|| $wppm_current_user_capability == 'wppm_admin'){ ?>
286 + <span class="wppm-add-new-btn btn-primary" id="wppm_add_new_project_btn" onclick="wppm_add_new_project()" style="background-color:<?php echo esc_attr($appearance_settings['list-header-button-background-color'])?>;color:<?php echo esc_attr($appearance_settings['list-header-button-text-color'])?>;"><span style="margin-right:5px;"><img id="wppm_add_new_project_icon" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/plus_icon.svg'); ?>" alt="plus_icon"></span><span><?php echo esc_html_e('Add New','taskbuilder');?></span></span>
287 + <?php } ?>
288 + <span class="wppm-add-new-btn btn-primary" id="wppm_project_list" onclick="wppm_get_project_list()" style="background-color:<?php echo esc_attr($appearance_settings['list-header-button-background-color'])?>;color:<?php echo esc_attr($appearance_settings['list-header-button-text-color'])?>;"><span style="margin-right:5px;"><img id ="wppm_project_list_icon" src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/list-symbol.svg'); ?>" alt="list-symbol"></span><span><?php echo esc_html_e('Project List','taskbuilder');?></span></span>
289 + <?php if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_manager'|| $wppm_current_user_capability == 'wppm_admin' ){ ?>
290 + <span class="wppm-add-new-btn btn-primary"" id="wppm_archieve_project_btn" title="Archive Project" onclick="wppm_archieve_project_list()" style="background-color:<?php echo esc_attr($appearance_settings['list-header-button-background-color'])?>;color:<?php echo esc_attr($appearance_settings['list-header-button-text-color'])?>;"><img src="<?php echo esc_url( WPPM_PLUGIN_URL . 'asset/images/archive_project.svg'); ?>" alt="archive"><span style="margin-left:5px;"><span><?php echo esc_html_e('Archive Project','taskbuilder');?></span></span>
291 + <?php } ?>
168 292 </div>
169 293 </div>
170 294 <div style="display:flex;justify-content:space-between;margin-top:20px;flex-wrap: wrap;">
171 295 <div style="display:flex;flex-wrap: wrap;">
@@ -195,22 +319,76 @@
195 319 </div>
196 320 </div>
197 321 <div class="wppm-filter-item">
198 322 <label for="wppm_project_filter"> <?php echo esc_html_e('Filter','taskbuilder');?></label>
199 - <select id="wppm_project_filter" name="wppm_project_filter" onchange="wppm_apply_project_filter()">
323 + <select id="wppm_project_filter" name="wppm_project_filter" onchange="wppm_apply_project_filter(<?php echo $is_archieved ?>)">
200 324 <option value="all"<?php echo ($filter_by == "all")? 'selected':""?>><?php echo esc_html_e('All','taskbuilder');?></option>
201 - <option style="<?php echo $new_style ?>" value="1" <?php echo ($filter_by == "1")? 'selected':""?>><?php echo esc_html_e($new_status_name,'taskbuilder');?></option>
202 - <option style="<?php echo $inp_status_style ?>" value="2" <?php echo ($filter_by == "2")? 'selected':""?>><?php echo esc_html_e($inp_status_name,'taskbuilder');?></option>
203 - <option style="<?php echo $hold_status_style ?>" value="3" <?php echo ($filter_by == "3")? 'selected':""?>><?php echo esc_html_e($hold_status_name,'taskbuilder');?></option>
204 - <option style="<?php echo $complete_status_style ?>" value="4" <?php echo ($filter_by == "4")? 'selected':""?>><?php echo esc_html_e($completed_status_name,'taskbuilder');?></option>
325 + <option style="<?php echo esc_attr($new_style) ?>" value="1" <?php echo ($filter_by == "1")? 'selected':""?>><?php echo esc_html($new_status_name);?></option>
326 + <option style="<?php echo esc_attr($inp_status_style) ?>" value="2" <?php echo ($filter_by == "2")? 'selected':""?>><?php echo esc_html($inp_status_name);?></option>
327 + <option style="<?php echo esc_attr($hold_status_style) ?>" value="3" <?php echo ($filter_by == "3")? 'selected':""?>><?php echo esc_html($hold_status_name);?></option>
328 + <option style="<?php echo esc_attr($complete_status_style) ?>" value="4" <?php echo ($filter_by == "4")? 'selected':""?>><?php echo esc_html($completed_status_name);?></option>
205 329 <option value="mine" <?php echo ($filter_by == "mine")? 'selected':""?>><?php echo esc_html_e('Mine','taskbuilder');?></option>
206 330 <option value="unassigned" <?php echo ($filter_by == "unassigned")? 'selected':""?>><?php echo esc_html_e('Unassigned','taskbuilder');?></option>
207 331 <option value="overdue" <?php echo ($filter_by == "overdue")? 'selected':""?>><?php echo esc_html_e('Overdue','taskbuilder');?></option>
208 332 </select>
209 333 </div>
334 + <div class="tb-filters" style="display:flex;margin-left: 4px;">
335 + <div class="tb-filter-bar">
336 + <span id="tb-advanced-toggle" class="tb-btn" style="margin: 10px 10px 10px 2px !important;">
337 + <?php echo esc_html_e('⚙️ Filters', 'taskbuilder'); ?>
338 + </span>
339 + <div id="tb-active-filters" class="tb-chips"></div>
340 + <div id="tb-advanced-panel" class="tb-popover">
341 + <div class="tb-mobile-header">
342 + <span><?php echo esc_html_e('Filters', 'taskbuilder'); ?></span>
343 + <button type="button" id="tb-close-filters">✕</button>
344 + </div>
345 + <div class="tb-arrow"></div>
346 + <div class="tb-section">
347 + <h4> <?php echo esc_html_e('Created By', 'taskbuilder'); ?></h4>
348 + <select id="tb-created-by" class="form-control" multiple>
349 + <?php if(!empty($pb_users)){ foreach($pb_users as $pb_user): ?>
350 + <option value="<?php echo esc_attr($pb_user->ID); ?>"><?php echo esc_html($pb_user->display_name); ?></option>
351 + <?php endforeach; } ?>
352 + </select>
353 + <h4> <?php echo esc_html_e('Co-workers', 'taskbuilder'); ?></h4>
354 + <select id="tb-assigned" class="form-control" multiple>
355 + <?php
356 + if(!empty($all_assigned_proj_users)){
357 + foreach($all_assigned_proj_users as $auid){
358 + $auser = get_userdata($auid);
359 + if($auser){ ?>
360 + <option value="<?php echo esc_attr($auid); ?>"><?php echo esc_html($auser->display_name); ?></option>
361 + <?php }
362 + }
363 + }
364 + ?>
365 + </select>
366 + </div>
367 + <div class="tb-section">
368 + <h4> <?php echo esc_html_e('Category', 'taskbuilder'); ?></h4>
369 + <select id="tb-category" class="form-control" multiple>
370 + <?php if(!empty($categories)){ foreach($categories as $pb_cat){ ?>
371 + <option value="<?php echo esc_attr($pb_cat->id); ?>"><?php echo esc_html($pb_cat->name); ?></option>
372 + <?php } } ?>
373 + </select>
374 + </div>
375 + <div class="tb-section">
376 + <h4> <?php echo esc_html_e('Date', 'taskbuilder'); ?></h4>
377 + <input type="date" class="form-control" id="tb-start-date">
378 + <input type="date" class="form-control" id="tb-end-date">
379 + </div>
380 + <div id="tb-filter-actions">
381 + <button class="wppm-submit-btn" id="tb-apply-filter" type="button"><?php echo esc_html_e('Apply', 'taskbuilder'); ?></button>
382 + <button class="wppm_reset_btn" id="tb-reset-filter" type="button"><?php echo esc_html_e('Reset', 'taskbuilder'); ?></button>
383 + </div>
384 + </div>
385 + </div>
386 + <div id="tb-backdrop"></div>
387 + </div>
210 388 <div class="wppm_display_submit">
211 389 <div class="wppm-filter-actions">
212 - <span class="wppm-link" onclick="wppm_pl_reset_filter()"> <?php echo esc_html_e('Reset','taskbuilder');?></span>
390 + <span class="wppm-link" onclick="wppm_pl_reset_filter(<?php echo $is_archieved ?>)"> <?php echo esc_html_e('Reset','taskbuilder');?></span>
213 391 </div>
214 392 </div>
215 393 </div>
216 394 </div>
@@ -278,27 +456,27 @@
278 456 foreach( $wppm_fillter as $project ){
279 457 $total_projects++;
280 458 $proejctdata = $wppmfunction->get_project($project->id);
281 459 $wppm_proj_duration = $wppmfunction->wppm_get_duration($project->start_date,$project->end_date);
282 - $pstatus= esc_sql($project->status);
460 + $pstatus= absint($project->status);
283 461 $status = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}wppm_project_statuses where id='$pstatus'" );
284 462 $users = explode(",",$project->users);
285 - $pid= esc_sql($project->id);
463 + $pid= absint($project->id);
286 464 if(isset($project->cat_id)){
287 - $pcat_id = esc_sql($project->cat_id);
465 + $pcat_id = absint($project->cat_id);
288 466 $category = $wpdb->get_var( "SELECT name FROM {$wpdb->prefix}wppm_project_categories where id='$pcat_id'" );
289 467 }
290 468 if(isset($project->id)){
291 469 if($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin'){
292 - $no_of_tasks = $wpdb->get_var("SELECT count(*) FROM {$wpdb->prefix}wppm_task WHERE project='$pid' ");
470 + $no_of_tasks = $wpdb->get_var("SELECT count(*) FROM {$wpdb->prefix}wppm_task WHERE project='$pid' AND (parent_task_id = 0 OR parent_task_id IS NULL) ");
293 471 }else{
294 - $query =("SELECT count(*) FROM
472 + $query =("SELECT count(*) FROM
295 473 ( SELECT Task.*
296 474 FROM {$wpdb->prefix}wppm_task AS Task
297 475 Left join {$wpdb->prefix}wppm_project proj ON Task.project = proj.id
298 476 Left join {$wpdb->prefix}wppm_project_users proj_users ON Task.project = proj_users.proj_id
299 477 Left join {$wpdb->prefix}wppm_project_meta proj_meta ON proj.id = proj_meta.project_id
300 - where Task.project = '$pid' AND ((FIND_IN_SET('$current_user->ID',Task.users)>0) OR (Task.created_by= '$cu_id') OR (proj_users.user_id = '$cu_id' AND proj_users.role_id = 1 ) OR (proj.id = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) OR ( Task.project = proj.id AND proj.created_by='$cu_id')) Group by Task.id ) AS Task");
478 + where Task.project = '$pid' AND (Task.parent_task_id = 0 OR Task.parent_task_id IS NULL) AND ((FIND_IN_SET('$current_user->ID',Task.users)>0) OR (Task.created_by= '$cu_id') OR (proj_users.user_id = '$cu_id' AND proj_users.role_id = 1 ) OR (proj.id = proj_meta.project_id AND proj_meta.meta_key='public_project' AND proj_meta.meta_value=1) OR ( Task.project = proj.id AND proj.created_by='$cu_id')) Group by Task.id ) AS Task");
301 479 $no_of_tasks = $wpdb->get_var($query);
302 480 }
303 481 $no_of_tasks = apply_filters('wppm_no_of_task_proj_list_query',$no_of_tasks,$project->id);
304 482 }
@@ -399,10 +577,10 @@
399 577 <label for="wppm_bulk_select_<?php echo esc_attr($project->id) ?>"></label>
400 578 </div>
401 579 </div>
402 580 </td>
403 - <td onmouseover="link=true;"><?php echo esc_html_e($project->project_name,'taskbuilder') ?></td>
404 - <td onmouseover="link=true;"><span class="wppm_td_project_status" style="background-color:<?php echo esc_attr($status->bg_color);?>; color: <?php echo esc_attr($status->color); ?>"><?php echo esc_html_e($status->name,'taskbuilder') ?></span></td>
581 + <td onmouseover="link=true;"><?php echo esc_html($project->project_name) ?></td>
582 + <td onmouseover="link=true;"><span class="wppm_td_project_status" style="background-color:<?php echo esc_attr($status->bg_color);?>; color: <?php echo esc_attr($status->color); ?>"><?php echo esc_html($status->name) ?></span></td>
405 583 <td onmouseover="link=true;">
406 584 <?php
407 585 $i=0;
408 586 if(!empty(array_filter($users))){
@@ -411,9 +589,9 @@
411 589 if( $i <= 4 ){
412 590 $user_info = get_user_by('id', $user );
413 591 if(!empty($user_info)){
414 592 ?>
415 - <a href="#" title="<?php echo esc_html_e($user_info->display_name) ?>">
593 + <a href="#" title="<?php echo esc_html($user_info->display_name) ?>">
416 594 <?php echo get_avatar($user_info->ID, 25, "mysteryman");?>
417 595 </a> <?php
418 596 }
419 597 }
@@ -418,9 +596,9 @@
418 596 }
419 597 }
420 598 }
421 599 } else{
422 - _e('None','wp_projects');
600 + esc_html_e('None','taskbuilder');
423 601 }
424 602 if($i > 4){
425 603 ?>
426 604 <a href="#" class="wppm_avatar">
@@ -427,9 +605,9 @@
427 605 <span id="wppm_avatar" style="background-color:black;" class="avatar">+<?php echo esc_html($i-4) ?></span>
428 606 </a>
429 607 <?php } ?>
430 608 </td>
431 - <td onmouseover="link=true;" class="wppm_table_td"><?php echo isset($category) ? esc_html_e($category,'taskbuilder'): "" ?></td>
609 + <td onmouseover="link=true;" class="wppm_table_td"><?php echo isset($category) ? esc_html($category): "" ?></td>
432 610 <?php if($wppm_default_project_date==1 && $wppm_deafault_time_duration_project==0){ ?>
433 611 <td onmouseover="link=true;" class="wppm_table_td"><?php echo isset($proj_start_date) ? esc_html($proj_start_date): "" ?></td>
434 612 <?php
435 613 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')) {
@@ -483,14 +661,14 @@
483 661 </span>
484 662 <span
485 663 <?php echo esc_html($prev_class) ?>
486 664 style="<?php echo (isset($prev_class) && esc_attr($prev_class) == 'disabled') ? 'display:none;':'display:block;'?>">
487 - <a class="wppm_pagination_prev" onclick="return wppm_load_prev_page(<?php echo esc_attr($prev_page_no) ?>,<?php echo esc_attr($page_no) ?>,'<?php echo esc_attr($sort_by)?>','<?php echo esc_attr($order) ?>');"><?php echo esc_html_e('PREV','taskbuilder');?></a>
665 + <a class="wppm_pagination_prev" onclick="return wppm_load_prev_page(<?php echo esc_attr($prev_page_no) ?>,<?php echo esc_attr($page_no) ?>,'<?php echo esc_attr($sort_by)?>','<?php echo esc_attr($order) ?>','<?php echo esc_attr($is_archieved)?>');"><?php echo esc_html_e('PREV','taskbuilder');?></a>
488 666 </span>
489 667 <span
490 668 <?php echo esc_attr($next_class) ?>
491 669 style="<?php echo (isset($next_class) && $next_class == 'disabled')?'display:none;':'display:block;'?>cursor:pointer;">
492 - <a class="wppm_pagination_next" onclick="return wppm_load_next_page('<?php echo esc_attr($next_page_no) ?>','<?php echo esc_attr($page_no) ?>','<?php echo esc_attr($sort_by)?>','<?php echo esc_attr($order) ?>');"><?php echo esc_html_e('NEXT','taskbuilder');?></a>
670 + <a class="wppm_pagination_next" onclick="return wppm_load_next_page('<?php echo esc_attr($next_page_no) ?>','<?php echo esc_attr($page_no) ?>','<?php echo esc_attr($sort_by)?>','<?php echo esc_attr($order) ?>','<?php echo esc_attr($is_archieved)?>');"><?php echo esc_html_e('NEXT','taskbuilder');?></a>
493 671 </span>
494 672 </div>
495 673 </div>
496 674 </div>
@@ -511,15 +689,111 @@
511 689 }
512 690 #wppm_project_table tr:hover td{
513 691 color: <?php echo esc_attr($appearance_settings['list-item-hover-text-color'])?>!important;
514 692 }
693 + #wppm_add_new_project_btn:hover,#wppm_project_list:hover,#wppm_archieve_project_btn:hover{
694 + background-color: <?php echo esc_attr($appearance_settings['list-header-button-hover-color'])?>!important;
695 + }
515 696 </style>
516 697 <script type="text/javascript">
517 698 jQuery( document ).ready( function( jQuery ) {
699 + let createdBy = <?php echo wp_json_encode(array_map('strval', $advanced_filter['created_by'] ?? [])); ?>;
700 + let assignedUsers = <?php echo wp_json_encode(array_map('strval', $advanced_filter['assigned'] ?? [])); ?>;
701 + let categoryIds = <?php echo wp_json_encode(array_map('strval', $advanced_filter['category'] ?? [])); ?>;
702 + jQuery('#tb-created-by').select2({ width: '100%', dropdownParent: jQuery('#tb-advanced-panel') });
703 + jQuery('#tb-assigned').select2({ width: '100%', dropdownParent: jQuery('#tb-advanced-panel') });
704 + jQuery('#tb-category').select2({ width: '100%', dropdownParent: jQuery('#tb-advanced-panel') });
705 + jQuery('#tb-created-by').val(createdBy).trigger('change');
706 + jQuery('#tb-assigned').val(assignedUsers).trigger('change');
707 + jQuery('#tb-category').val(categoryIds).trigger('change');
708 + jQuery('#tb-start-date').val('<?php echo esc_attr($advanced_filter['start_date'] ?? ''); ?>');
709 + jQuery('#tb-end-date').val('<?php echo esc_attr($advanced_filter['end_date'] ?? ''); ?>');
710 +
711 + window.projectFilters = window.projectFilters || {
712 + created_by: createdBy,
713 + assigned: assignedUsers,
714 + category: categoryIds,
715 + start_date: '<?php echo esc_js($advanced_filter['start_date'] ?? ''); ?>',
716 + end_date: '<?php echo esc_js($advanced_filter['end_date'] ?? ''); ?>'
717 + };
718 +
719 + jQuery(document).off("click", "#tb-apply-filter").on("click", "#tb-apply-filter", function (e) {
720 + e.preventDefault();
721 + window.projectFilters = {
722 + created_by: jQuery("#tb-created-by").val() || [],
723 + assigned: jQuery("#tb-assigned").val() || [],
724 + category: jQuery("#tb-category").val() || [],
725 + start_date: jQuery("#tb-start-date").val() || "",
726 + end_date: jQuery("#tb-end-date").val() || ""
727 + };
728 + renderActiveFilters(window.projectFilters);
729 + setProjectListFilterCookie(window.projectFilters);
730 + triggerProjectFilter(1, window.projectFilters, <?php echo (int) $is_archieved; ?>);
731 + });
732 +
733 + jQuery(document).off("click", ".tb-remove").on("click", ".tb-remove", function () {
734 + let key = jQuery(this).attr("data-key");
735 + let value = jQuery(this).attr("data-value");
736 + if (key === "date") {
737 + window.projectFilters.start_date = "";
738 + window.projectFilters.end_date = "";
739 + jQuery("#tb-start-date").val("");
740 + jQuery("#tb-end-date").val("");
741 + } else {
742 + window.projectFilters[key] = (window.projectFilters[key] || [])
743 + .map(String)
744 + .filter(v => v !== String(value));
745 + jQuery(`#tb-${key}`).val(window.projectFilters[key]).trigger("change");
746 + }
747 + jQuery(this).closest(".tb-chip").remove();
748 + syncUIWithFilters(window.projectFilters);
749 + setProjectListFilterCookie(window.projectFilters);
750 + triggerProjectFilter(1, window.projectFilters, <?php echo (int) $is_archieved; ?>);
751 + });
752 +
753 + jQuery(document).off("click", "#tb-reset-filter").on("click", "#tb-reset-filter", function () {
754 + resetProjectFilters(<?php echo (int) $is_archieved; ?>);
755 + });
756 +
757 + let savedProjectFilters = getProjectListFilterCookie();
758 + if (savedProjectFilters && typeof savedProjectFilters === "object") {
759 + window.projectFilters = {
760 + created_by: savedProjectFilters.created_by || [],
761 + assigned: savedProjectFilters.assigned || [],
762 + category: savedProjectFilters.category || [],
763 + start_date: savedProjectFilters.start_date || "",
764 + end_date: savedProjectFilters.end_date || ""
765 + };
766 + }
767 + setTimeout(function () {
768 + syncUIWithFilters(window.projectFilters);
769 + renderActiveFilters(window.projectFilters);
770 + }, 100);
771 +
772 + jQuery(document).off("click", "#tb-advanced-toggle").on("click", "#tb-advanced-toggle", function (e) {
773 + e.stopPropagation();
774 + jQuery("#tb-advanced-panel").toggleClass("tb-open");
775 + });
776 + jQuery(document).off("click", "#tb-backdrop").on("click", "#tb-backdrop", function () {
777 + jQuery("#tb-advanced-panel").removeClass("tb-open");
778 + jQuery(this).removeClass("active");
779 + });
780 + jQuery(document).off("click.tbProjOutside").on("click.tbProjOutside", function (e) {
781 + if (window.innerWidth > 768) {
782 + if (!jQuery(e.target).closest("#tb-advanced-panel, #tb-advanced-toggle").length) {
783 + jQuery("#tb-advanced-panel").removeClass("tb-open");
784 + }
785 + }
786 + });
787 + jQuery(document).off("click", "#tb-close-filters").on("click", "#tb-close-filters", function () {
788 + jQuery("#tb-advanced-panel").removeClass("tb-open");
789 + jQuery("#tb-backdrop").removeClass("active");
790 + });
791 +
518 792 jQuery("input[name='wppm_project_search_filter']").keypress(function(e) {
519 793 //Enter key
520 794 if (e.which == 13) {
521 - wppm_project_search_filter();
795 + wppm_project_search_filter(<?php echo $is_archieved ?>);
522 796 }
523 797 });
524 798 jQuery("#wppm_proj_name_th").hover(function(){
525 799 jQuery('#wppm_chevron_sort_up_project_name_img').show();