get_results( "SELECT * FROM {$wpdb->prefix}wppm_project_statuses" ); $categories = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}wppm_project_categories" ); $pb_users = get_users(array( 'orderby' => 'display_name', 'order' => 'ASC' )); $assigned_project_users = $wpdb->get_col( "SELECT DISTINCT users FROM {$wpdb->prefix}wppm_project WHERE users != ''" ); $all_assigned_proj_users = array(); foreach ( $assigned_project_users as $row ) { foreach ( explode( ',', $row ) as $uid ) { $uid = trim( $uid ); if ( $uid !== '' ) { $all_assigned_proj_users[] = $uid; } } } $all_assigned_proj_users = array_unique( $all_assigned_proj_users ); $appearance_settings = wp_parse_args( get_option( "wppm-ap-project-list", array() ), array( 'list-header-button-background-color' => '#0052CC', 'list-header-button-hover-color' => '#0065ff', 'list-header-button-text-color' => '#fff', ) ); $wppm_date_setting = get_option('wppm_date_setting'); $wppm_deafault_time_duration_project = get_option('wppm_display_time_duration_project'); $wppm_current_user_capability = get_user_meta( $current_user->ID, 'wppm_capability', true ); $proj_per_page = 20; $page_no = (isset($_POST['page_no'])) ? intval(sanitize_text_field($_POST['page_no'])): '0'; $page = isset($_POST['page']) ? sanitize_text_field(wp_unslash($_POST['page'])):""; $search_tag = isset($_POST['project_search']) ? sanitize_text_field($_POST['project_search']) : ''; $order = isset($_POST['order']) ? sanitize_text_field($_POST['order']) :"ASC"; $sort_by = isset($_POST['sort_by']) ? sanitize_text_field($_POST['sort_by']):"project_name"; $filter_by = isset($_POST['wppm_project_filter']) ? sanitize_text_field($_POST['wppm_project_filter']) : "all"; $is_archieved = !empty($_POST['is_archieved']) ? 1 : 0; if ( isset( $_POST['filters'] ) ) { if ( is_string( $_POST['filters'] ) ) { $advanced_filter = json_decode( stripslashes( sanitize_text_field( wp_unslash( $_POST['filters'] ) ) ), true ); } elseif ( is_array( $_POST['filters'] ) ) { $raw_filters = wp_unslash( $_POST['filters'] ); $advanced_filter = array( 'created_by' => array_map( 'absint', (array) ( $raw_filters['created_by'] ?? array() ) ), 'assigned' => array_map( 'absint', (array) ( $raw_filters['assigned'] ?? array() ) ), 'category' => array_map( 'absint', (array) ( $raw_filters['category'] ?? array() ) ), 'start_date' => sanitize_text_field( $raw_filters['start_date'] ?? '' ), 'end_date' => sanitize_text_field( $raw_filters['end_date'] ?? '' ), ); } else { $advanced_filter = array(); } } elseif ( ! empty( $_COOKIE['tb_proj_list_filters'] ) ) { $advanced_filter = json_decode( stripslashes( sanitize_text_field( wp_unslash( $_COOKIE['tb_proj_list_filters'] ) ) ), true ); } else { $advanced_filter = array(); } if ( ! is_array( $advanced_filter ) ) { $advanced_filter = array(); } $current_date = wp_date('Y-m-d'); $wppm_pl_filter = "1=1"; $wppm_hide_completed_status_proj = get_option('wppm_hide_completed_status_proj'); $cu_id = esc_sql($current_user->ID); $wppm_hide_proj_statuses_from_frontend = get_option('wppm_hide_proj_statuses_from_frontend'); if(!empty($wppm_hide_proj_statuses_from_frontend)){ $wppm_hide_proj_statuses_from_frontend = explode(",",$wppm_hide_proj_statuses_from_frontend); } else { $wppm_hide_proj_statuses_from_frontend = ''; } $is_admin = ( $wppm_current_user_capability === 'wppm_admin' || current_user_can('manage_options') ) ? 1 : 0; $filters = array( 'sort_by' => $sort_by, 'order' => $order, 'search' => $search_tag, 'filter'=>$filter_by ); $pl_filters = isset( $_COOKIE['wppm_proj_filters'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['wppm_proj_filters'] ) ) : $filters; if(!is_array($pl_filters)){ $pl_filters = json_decode($pl_filters); $pl_filters_arr = (array) $pl_filters; } else{ $pl_filters_arr = $filters; } $search_tag = isset($_POST['project_search']) ? sanitize_text_field($_POST['project_search']) : $pl_filters_arr['search']; $order = isset($_POST['order']) ? sanitize_text_field($_POST['order']) :$pl_filters_arr['order']; $sort_by = isset($_POST['sort_by']) ? sanitize_text_field($_POST['sort_by']):$pl_filters_arr['sort_by']; $filter_by = isset($_POST['wppm_project_filter']) ? sanitize_text_field($_POST['wppm_project_filter']) : $pl_filters_arr['filter']; if($sort_by == ""){ $sort_by = 'project_name'; } $filters = array( 'sort_by' => $sort_by, 'order' => $order, 'search'=>$search_tag, 'filter'=>$filter_by ); setcookie('wppm_proj_filters',wp_json_encode( $filters ),time() + 3600); $allowed_sort_by = [ 'project_name' => 'project_name', 'status' => 'proj_statuses.name', 'category' => 'proj_categories.name', 'start_date' => 'start_date', 'end_date' => 'end_date', 'TIMESTAMPDIFF(SECOND, start_date, end_date)'=> 'TIMESTAMPDIFF(SECOND, start_date, end_date)' ]; // Resolve sort_by safely $sort_key = isset($pl_filters_arr['sort_by']) ? sanitize_text_field($pl_filters_arr['sort_by']) : 'project_name'; $sort_by = $allowed_sort_by[$sort_key] ?? 'project_name'; $order = ( isset($pl_filters_arr['order']) && strtoupper($pl_filters_arr['order']) === 'ASC' ) ? 'ASC' : 'DESC'; if($filter_by=='all'){ if($wppm_hide_completed_status_proj == 0){ $wppm_pl_filter = "status!='4'"; } } if($filter_by=='4'){ $wppm_pl_filter = "status='4'"; }elseif($filter_by=='overdue'){ $wppm_pl_filter = "status!='4' AND (CAST(end_date AS DATE)) < '$current_date'"; }elseif($filter_by == 'unassigned'){ $wppm_pl_filter = "users=''"; }elseif($filter_by == '1'){ $wppm_pl_filter = "status='1'"; }elseif($filter_by == '2'){ $wppm_pl_filter = "status='2'"; }elseif($filter_by == '3'){ $wppm_pl_filter = "status='3'"; }elseif($filter_by == 'mine'){ $wppm_pl_filter = "(FIND_IN_SET('$current_user->ID',users)>0)"; }elseif($filter_by == 'active'){ $wppm_pl_filter = " (FIND_IN_SET('$current_user->ID', users) OR created_by = '$current_user->ID' OR $is_admin = 1 ) AND status != 4"; } 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))){ foreach($wppm_hide_proj_statuses_from_frontend as $status){ $wppm_pl_filter .= " AND status != '$status'"; } } $advanced_conditions = array(); if ( ! empty( $advanced_filter['created_by'] ) ) { $created_by_ids = array_map( 'intval', (array) $advanced_filter['created_by'] ); $advanced_conditions[] = "created_by IN (" . implode( ',', $created_by_ids ) . ")"; } if ( ! empty( $advanced_filter['assigned'] ) ) { $assigned_ids = array_map( 'intval', (array) $advanced_filter['assigned'] ); $assigned_sql = array(); foreach ( $assigned_ids as $id ) { $assigned_sql[] = "FIND_IN_SET('$id', users)"; } $advanced_conditions[] = "(" . implode( ' OR ', $assigned_sql ) . ")"; } if ( ! empty( $advanced_filter['category'] ) ) { $category_ids = array_map( 'intval', (array) $advanced_filter['category'] ); $advanced_conditions[] = "cat_id IN (" . implode( ',', $category_ids ) . ")"; } if ( ! empty( $advanced_filter['start_date'] ) && preg_match( '/^\d{4}-\d{2}-\d{2}$/', $advanced_filter['start_date'] ) ) { $advanced_conditions[] = $wpdb->prepare( "(CAST(start_date AS DATE)) >= %s", $advanced_filter['start_date'] ); } if ( ! empty( $advanced_filter['end_date'] ) && preg_match( '/^\d{4}-\d{2}-\d{2}$/', $advanced_filter['end_date'] ) ) { $advanced_conditions[] = $wpdb->prepare( "(CAST(end_date AS DATE)) <= %s", $advanced_filter['end_date'] ); } if ( ! empty( $advanced_conditions ) ) { $wppm_pl_filter .= " AND " . implode( " AND ", $advanced_conditions ); } $wppm_project_time = get_option('wppm_project_time'); $wppm_default_project_date = get_option('wppm_default_project_date'); $sort_by = apply_filters('wppm_project_list_sort_by_query',$sort_by); $order = apply_filters('wppm_project_list_order_query',$order); $search_tag_text = '%'.$wpdb->esc_like($search_tag).'%'; if (!empty($search_tag)) { $search_tag_text = '%' . $wpdb->esc_like($search_tag) . '%'; $query = "SELECT Project.* FROM {$wpdb->prefix}wppm_project AS Project LEFT JOIN {$wpdb->prefix}wppm_project_statuses proj_statuses ON Project.status = proj_statuses.id LEFT JOIN {$wpdb->prefix}wppm_project_categories proj_categories ON Project.cat_id = proj_categories.id LEFT JOIN {$wpdb->base_prefix}users user ON FIND_IN_SET(user.ID, Project.users) > 0 LEFT JOIN {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id"; // SAFE search condition $search_sql = $wpdb->prepare( "(Project.project_name LIKE %s OR proj_statuses.name LIKE %s OR proj_categories.name LIKE %s OR user.display_name LIKE %s)", $search_tag_text, $search_tag_text, $search_tag_text, $search_tag_text ); if ($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') { // ✅ Admin (safe) $where = " WHERE $wppm_pl_filter AND $search_sql"; } else { // ✅ Non-admin (safe) $where = $wpdb->prepare( " WHERE $wppm_pl_filter AND $search_sql AND ( FIND_IN_SET(%d, Project.users) > 0 OR ( proj_meta.meta_key = 'public_project' AND proj_meta.meta_value = 1 ) OR Project.created_by = %d )", $current_user->ID, $cu_id ); } } else { if ($sort_by == 'project_name' || $sort_by == 'start_date' || $sort_by == 'end_date') { $query = "SELECT Project.* FROM {$wpdb->prefix}wppm_project AS Project LEFT JOIN {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id"; } else { $query = "SELECT Project.* FROM {$wpdb->prefix}wppm_project AS Project LEFT JOIN {$wpdb->prefix}wppm_project_statuses proj_statuses ON Project.status = proj_statuses.id LEFT JOIN {$wpdb->prefix}wppm_project_categories proj_categories ON Project.cat_id = proj_categories.id LEFT JOIN {$wpdb->prefix}wppm_project_meta proj_meta ON Project.id = proj_meta.project_id"; } if ($current_user->has_cap('manage_options') || $wppm_current_user_capability == 'wppm_admin') { $where = " WHERE $wppm_pl_filter"; } else { $where = $wpdb->prepare( " WHERE $wppm_pl_filter AND ( FIND_IN_SET(%d, Project.users) > 0 OR ( proj_meta.meta_key = 'public_project' AND proj_meta.meta_value = 1 ) OR Project.created_by = %d )", $current_user->ID, $cu_id ); } } $archived_where = ''; if ( isset( $is_archieved ) && $is_archieved === 1 ) { $archived_where = ' AND Project.is_archived = 1'; } else { $archived_where = ' AND Project.is_archived = 0'; } $where .= $archived_where; $no_of_rows = ( "SELECT count(*) FROM ($query"); $no_of_rows = apply_filters('wppm_project_list_no_of_rows',$no_of_rows,$wppm_pl_filter,$search_tag); $where = apply_filters('wppm_project_list_query_where',$where, $wppm_pl_filter,$search_tag); $query .= $where." Group by Project.id ORDER BY $sort_by $order"; $no_of_rows .= $where." Group by Project.id) AS Project"; $totalrows = $wpdb->get_var( $no_of_rows ); $query = apply_filters('wppm_project_list_query',$query); $limit_start=$page_no*$proj_per_page; $limit="\n LIMIT ".$limit_start.",".$proj_per_page." "; $query = $query.$limit; $wppm_fillter = $wpdb->get_results($query); $new_status_name = $wpdb->get_var( "SELECT name FROM {$wpdb->prefix}wppm_project_statuses where id='".esc_sql(1)."'" ); $inp_status_name = $wpdb->get_var( "SELECT name FROM {$wpdb->prefix}wppm_project_statuses where id='".esc_sql(2)."'" ); $hold_status_name = $wpdb->get_var( "SELECT name FROM {$wpdb->prefix}wppm_project_statuses where id='".esc_sql(3)."'" ); $completed_status_name = $wpdb->get_var( "SELECT name FROM {$wpdb->prefix}wppm_project_statuses where id='".esc_sql(4)."'" ); $new_style = (!empty($new_status_name))? "display:inline" :"display:none;"; $inp_status_style = (!empty($inp_status_name))? "display:inline" :"display:none;"; $hold_status_style = (!empty($hold_status_name))? "display:inline" :"display:none;"; $complete_status_style = (!empty($completed_status_name))? "display:inline" :"display:none;"; ?>