| @@ -4,18 +4,65 @@ | ||
| 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"; |
| 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 | +} | |
| 18 | 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); |
| @@ -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,9 +319,9 @@ | ||
| 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 | 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> |
| 202 | 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> |
| 203 | 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> |
| @@ -206,11 +330,65 @@ | ||
| 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 | } |
| @@ -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"> |
| @@ -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(); |