. /** * Filter API * * @package CoreAPI * @subpackage FilterAPI * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org * @copyright Copyright (C) 2002 - 2011 MantisBT Team - mantisbt-dev@lists.sourceforge.net * @link http://www.mantisbt.org * * @uses access_api.php * @uses authentication_api.php * @uses bug_api.php * @uses collapse_api.php * @uses columns_api.php * @uses config_api.php * @uses constant_inc.php * @uses current_user_api.php * @uses custom_field_api.php * @uses database_api.php * @uses date_api.php * @uses error_api.php * @uses event_api.php * @uses filter_constants_inc.php * @uses gpc_api.php * @uses helper_api.php * @uses lang_api.php * @uses logging_api.php * @uses print_api.php * @uses profile_api.php * @uses project_api.php * @uses relationship_api.php * @uses string_api.php * @uses tag_api.php * @uses user_api.php * @uses utility_api.php * @uses version_api.php */ require_api( 'access_api.php' ); require_api( 'authentication_api.php' ); require_api( 'bug_api.php' ); require_api( 'collapse_api.php' ); require_api( 'columns_api.php' ); require_api( 'config_api.php' ); require_api( 'constant_inc.php' ); require_api( 'current_user_api.php' ); require_api( 'custom_field_api.php' ); require_api( 'database_api.php' ); require_api( 'date_api.php' ); require_api( 'error_api.php' ); require_api( 'event_api.php' ); require_api( 'filter_constants_inc.php' ); require_api( 'gpc_api.php' ); require_api( 'helper_api.php' ); require_api( 'lang_api.php' ); require_api( 'logging_api.php' ); require_api( 'print_api.php' ); require_api( 'profile_api.php' ); require_api( 'project_api.php' ); require_api( 'relationship_api.php' ); require_api( 'string_api.php' ); require_api( 'tag_api.php' ); require_api( 'user_api.php' ); require_api( 'utility_api.php' ); require_api( 'version_api.php' ); /** * Allow plugins to define a set of class-based filters, and register/load * them here to be used by the rest of filter_api. * @return array Mapping of field name to filter object */ function filter_get_plugin_filters() { static $s_field_array = null; if ( is_null( $s_field_array ) ) { $s_field_array = array(); $t_all_plugin_filters = event_signal( 'EVENT_FILTER_FIELDS' ); foreach( $t_all_plugin_filters as $t_plugin => $t_plugin_filters ) { foreach( $t_plugin_filters as $t_callback => $t_plugin_filter_array ) { if ( is_array( $t_plugin_filter_array ) ) { foreach( $t_plugin_filter_array as $t_filter_class ) { if ( class_exists( $t_filter_class ) && is_subclass_of( $t_filter_class, 'MantisFilter' ) ) { $t_filter_object = new $t_filter_class(); $t_field_name = $t_plugin . '_' . $t_filter_object->field; $s_field_array[ $t_field_name ] = $t_filter_object; } } } } } } return $s_field_array; } /** * Get a permalink for the current active filter. The results of using these fields by other users * can be inconsistent with the original results due to fields like "Myself", "Current Project", * and due to access level. * @param array $p_custom_filter * @return string the search.php?xxxx or an empty string if no criteria applied. */ function filter_get_url( $p_custom_filter ) { $t_query = array(); if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_PROJECT_ID] ) ) { $t_project_id = $p_custom_filter[FILTER_PROPERTY_PROJECT_ID]; if( count( $t_project_id ) == 1 && $t_project_id[0] == META_FILTER_CURRENT ) { $t_project_id = array( helper_get_current_project(), ); } $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_PROJECT_ID, $t_project_id ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_SEARCH] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_SEARCH, $p_custom_filter[FILTER_PROPERTY_SEARCH] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_CATEGORY_ID] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_CATEGORY_ID, $p_custom_filter[FILTER_PROPERTY_CATEGORY_ID] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_REPORTER_ID] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_REPORTER_ID, $p_custom_filter[FILTER_PROPERTY_REPORTER_ID] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_STATUS] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_STATUS, $p_custom_filter[FILTER_PROPERTY_STATUS] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_MONITOR_USER_ID] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_MONITOR_USER_ID, $p_custom_filter[FILTER_PROPERTY_MONITOR_USER_ID] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_HANDLER_ID] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_HANDLER_ID, $p_custom_filter[FILTER_PROPERTY_HANDLER_ID] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_NOTE_USER_ID] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_NOTE_USER_ID, $p_custom_filter[FILTER_PROPERTY_NOTE_USER_ID] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_SEVERITY] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_SEVERITY, $p_custom_filter[FILTER_PROPERTY_SEVERITY] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_RESOLUTION] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_RESOLUTION, $p_custom_filter[FILTER_PROPERTY_RESOLUTION] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_PRIORITY] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_PRIORITY, $p_custom_filter[FILTER_PROPERTY_PRIORITY] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_VIEW_STATE] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_VIEW_STATE, $p_custom_filter[FILTER_PROPERTY_VIEW_STATE] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_STICKY] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_STICKY, $p_custom_filter[FILTER_PROPERTY_STICKY] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_VERSION] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_VERSION, $p_custom_filter[FILTER_PROPERTY_VERSION] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_BUILD] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_BUILD, $p_custom_filter[FILTER_PROPERTY_BUILD] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_FIXED_IN_VERSION] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_FIXED_IN_VERSION, $p_custom_filter[FILTER_PROPERTY_FIXED_IN_VERSION] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_TARGET_VERSION] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_TARGET_VERSION, $p_custom_filter[FILTER_PROPERTY_TARGET_VERSION] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_SORT_FIELD_NAME] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_SORT_FIELD_NAME, $p_custom_filter[FILTER_PROPERTY_SORT_FIELD_NAME] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_SORT_DIRECTION] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_SORT_DIRECTION, $p_custom_filter[FILTER_PROPERTY_SORT_DIRECTION] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_ISSUES_PER_PAGE] ) ) { if( $p_custom_filter[FILTER_PROPERTY_ISSUES_PER_PAGE] != config_get( 'default_limit_view' ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_ISSUES_PER_PAGE, $p_custom_filter[FILTER_PROPERTY_ISSUES_PER_PAGE] ); } } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] ) ) { if( $p_custom_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] != config_get( 'default_show_changed' ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_HIGHLIGHT_CHANGED, $p_custom_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] ); } } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_HIDE_STATUS] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_HIDE_STATUS, $p_custom_filter[FILTER_PROPERTY_HIDE_STATUS] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_FILTER_BY_DATE] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_FILTER_BY_DATE, $p_custom_filter[FILTER_PROPERTY_FILTER_BY_DATE] ); # The start and end dates are only applicable if filter by date is set. if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_START_DAY] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_START_DAY, $p_custom_filter[FILTER_PROPERTY_START_DAY] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_END_DAY] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_END_DAY, $p_custom_filter[FILTER_PROPERTY_END_DAY] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_START_MONTH] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_START_MONTH, $p_custom_filter[FILTER_PROPERTY_START_MONTH] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_END_MONTH] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_END_MONTH, $p_custom_filter[FILTER_PROPERTY_END_MONTH] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_START_YEAR] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_START_YEAR, $p_custom_filter[FILTER_PROPERTY_START_YEAR] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_END_YEAR] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_END_YEAR, $p_custom_filter[FILTER_PROPERTY_END_YEAR] ); } } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_RELATIONSHIP_TYPE] ) ) { if( $p_custom_filter[FILTER_PROPERTY_RELATIONSHIP_TYPE] != -1 ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_RELATIONSHIP_TYPE, $p_custom_filter[FILTER_PROPERTY_RELATIONSHIP_TYPE] ); } } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_RELATIONSHIP_BUG] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_RELATIONSHIP_BUG, $p_custom_filter[FILTER_PROPERTY_RELATIONSHIP_BUG] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_PLATFORM] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_PLATFORM, $p_custom_filter[FILTER_PROPERTY_PLATFORM] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_OS] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_OS, $p_custom_filter[FILTER_PROPERTY_OS] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_OS_BUILD] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_OS_BUILD, $p_custom_filter[FILTER_PROPERTY_OS_BUILD] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_TAG_STRING] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_TAG_STRING, $p_custom_filter[FILTER_PROPERTY_TAG_STRING] ); } if( !filter_field_is_any( $p_custom_filter[FILTER_PROPERTY_TAG_SELECT] ) ) { $t_query[] = filter_encode_field_and_value( FILTER_PROPERTY_TAG_SELECT, $p_custom_filter[FILTER_PROPERTY_TAG_SELECT] ); } if( isset( $p_custom_filter['custom_fields'] ) ) { foreach( $p_custom_filter['custom_fields'] as $t_custom_field_id => $t_custom_field_values ) { if( !filter_field_is_any( $t_custom_field_values ) ) { $t_query[] = filter_encode_field_and_value( 'custom_field_' . $t_custom_field_id, $t_custom_field_values ); } } } # Allow plugins to add filter fields $t_plugin_filter_array = filter_get_plugin_filters(); foreach( $t_plugin_filter_array as $t_field_name => $t_filter_object ) { if( !filter_field_is_any( $p_custom_filter[ $t_field_name ] ) ) { $t_query[] = filter_encode_field_and_value( $t_field_name, $p_custom_filter[ $t_field_name ], $t_filter_object->type ); } } if( count( $t_query ) > 0 ) { $t_query_str = implode( $t_query, '&' ); $t_url = config_get( 'path' ) . 'search.php?' . $t_query_str; } else { $t_url = ''; } return $t_url; } /** * Encodes a field and it's value for the filter URL. This handles the URL encoding * and arrays. * @param string $p_field_name The field name. * @param string $p_field_value The field value (can be an array) * @return string url encoded string */ function filter_encode_field_and_value( $p_field_name, $p_field_value, $p_field_type=null ) { $t_query_array = array(); if( is_array( $p_field_value ) ) { $t_count = count( $p_field_value ); if( $t_count > 1 || $p_field_type == FILTER_TYPE_MULTI_STRING || $p_field_type == FILTER_TYPE_MULTI_INT ) { foreach( $p_field_value as $t_value ) { $t_query_array[] = urlencode( $p_field_name . '[]' ) . '=' . urlencode( $t_value ); } } else if( $t_count == 1 ) { $t_query_array[] = urlencode( $p_field_name ) . '=' . urlencode( $p_field_value[0] ); } } else { $t_query_array[] = urlencode( $p_field_name ) . '=' . urlencode( $p_field_value ); } return implode( $t_query_array, '&' ); } # ========================================================================== # GENERAL FUNCTIONS = # ========================================================================== /** * Checks the supplied value to see if it is an ANY value. * @param string $p_field_value - The value to check. * @return bool true for "ANY" values and false for others. "ANY" means filter criteria not active. */ function filter_field_is_any( $p_field_value ) { if( is_array( $p_field_value ) ) { if( count( $p_field_value ) == 0 ) { return true; } foreach( $p_field_value as $t_value ) { if(( META_FILTER_ANY == $t_value ) && ( is_numeric( $t_value ) ) ) { return true; } } } else { if( is_string( $p_field_value ) && is_blank( $p_field_value ) ) { return true; } if( is_bool( $p_field_value ) && !$p_field_value ) { return true; } if(( META_FILTER_ANY == $p_field_value ) && ( is_numeric( $p_field_value ) ) ) { return true; } } return false; } /** * Checks the supplied value to see if it is a NONE value. * @param string $p_field_value - The value to check. * @return bool true for "NONE" values and false for others. * @todo is a check for these necessary? if ( ( $t_filter_value === 'none' ) || ( $t_filter_value === '[none]' ) ) */ function filter_field_is_none( $p_field_value ) { if( is_array( $p_field_value ) ) { foreach( $p_field_value as $t_value ) { if(( META_FILTER_NONE == $t_value ) && ( is_numeric( $t_value ) ) ) { return true; } } } else { if( is_string( $p_field_value ) && is_blank( $p_field_value ) ) { return false; } if(( META_FILTER_NONE == $p_field_value ) && ( is_numeric( $p_field_value ) ) ) { return true; } } return false; } /** * Checks the supplied value to see if it is a MYSELF value. * @param string $p_field_value - The value to check. * @return bool true for "MYSELF" values and false for others. */ function filter_field_is_myself( $p_field_value ) { return( META_FILTER_MYSELF == $p_field_value ? TRUE : FALSE ); } /** * @param $p_count * @param $p_per_page * @return int */ function filter_per_page( $p_filter, $p_count, $p_per_page ) { $p_per_page = (( NULL == $p_per_page ) ? (int) $p_filter[FILTER_PROPERTY_ISSUES_PER_PAGE] : $p_per_page ); $p_per_page = (( 0 == $p_per_page || -1 == $p_per_page ) ? $p_count : $p_per_page ); return (int) abs( $p_per_page ); } /** * Use $p_count and $p_per_page to determine how many pages to split this list up into. * For the sake of consistency have at least one page, even if it is empty. * @param $p_count * @param $p_per_page * @return $t_page_count */ function filter_page_count( $p_count, $p_per_page ) { $t_page_count = ceil( $p_count / $p_per_page ); if( $t_page_count < 1 ) { $t_page_count = 1; } return $t_page_count; } /** * Checks to make sure $p_page_number isn't past the last page. * and that $p_page_number isn't before the first page * @param $p_page_number * @param $p_page_count */ function filter_valid_page_number( $p_page_number, $p_page_count ) { if( $p_page_number > $p_page_count ) { $p_page_number = $p_page_count; } if( $p_page_number < 1 ) { $p_page_number = 1; } return $p_page_number; } /** * Figure out the offset into the db query, offset is which record to start querying from * @param int $p_page_number * @param int $p_per_page * @return int */ function filter_offset( $p_page_number, $p_per_page ) { return(( (int) $p_page_number -1 ) * (int) $p_per_page ); } /** * Make sure that our filters are entirely correct and complete (it is possible that they are not). * We need to do this to cover cases where we don't have complete control over the filters given.s * @param array $p_filter_arr * @return mixed * @todo function needs to be abstracted */ function filter_ensure_valid_filter( $p_filter_arr ) { # extend current filter to add information passed via POST if( !isset( $p_filter_arr['_version'] ) ) { $p_filter_arr['_version'] = config_get( 'cookie_version' ); } $t_cookie_vers = (int) utf8_substr( $p_filter_arr['_version'], 1 ); if( utf8_substr( config_get( 'cookie_version' ), 1 ) > $t_cookie_vers ) { # if the version is old, update it $p_filter_arr['_version'] = config_get( 'cookie_version' ); } if( !isset( $p_filter_arr['_view_type'] ) ) { $p_filter_arr['_view_type'] = gpc_get_string( 'view_type', 'simple' ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_ISSUES_PER_PAGE] ) ) { $p_filter_arr[FILTER_PROPERTY_ISSUES_PER_PAGE] = gpc_get_int( FILTER_PROPERTY_ISSUES_PER_PAGE, config_get( 'default_limit_view' ) ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_HIGHLIGHT_CHANGED] ) ) { $p_filter_arr[FILTER_PROPERTY_HIGHLIGHT_CHANGED] = config_get( 'default_show_changed' ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_STICKY] ) ) { $p_filter_arr[FILTER_PROPERTY_STICKY] = gpc_string_to_bool( config_get( 'show_sticky_issues' ) ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_SORT_FIELD_NAME] ) ) { $p_filter_arr[FILTER_PROPERTY_SORT_FIELD_NAME] = "last_updated"; } if( !isset( $p_filter_arr[FILTER_PROPERTY_SORT_DIRECTION] ) ) { $p_filter_arr[FILTER_PROPERTY_SORT_DIRECTION] = "DESC"; } if( !isset( $p_filter_arr[FILTER_PROPERTY_PLATFORM] ) ) { $p_filter_arr[FILTER_PROPERTY_PLATFORM] = array( 0 => META_FILTER_ANY, ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_OS] ) ) { $p_filter_arr[FILTER_PROPERTY_OS] = array( 0 => META_FILTER_ANY, ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_OS_BUILD] ) ) { $p_filter_arr[FILTER_PROPERTY_OS_BUILD] = array( 0 => META_FILTER_ANY, ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_PROJECT_ID] ) ) { $p_filter_arr[FILTER_PROPERTY_PROJECT_ID] = array( 0 => META_FILTER_CURRENT, ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_START_MONTH] ) ) { $p_filter_arr[FILTER_PROPERTY_START_MONTH] = gpc_get_string( FILTER_PROPERTY_START_MONTH, date( 'm' ) ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_START_DAY] ) ) { $p_filter_arr[FILTER_PROPERTY_START_DAY] = gpc_get_string( FILTER_PROPERTY_START_DAY, 1 ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_START_YEAR] ) ) { $p_filter_arr[FILTER_PROPERTY_START_YEAR] = gpc_get_string( FILTER_PROPERTY_START_YEAR, date( 'Y' ) ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_END_MONTH] ) ) { $p_filter_arr[FILTER_PROPERTY_END_MONTH] = gpc_get_string( FILTER_PROPERTY_END_MONTH, date( 'm' ) ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_END_DAY] ) ) { $p_filter_arr[FILTER_PROPERTY_END_DAY] = gpc_get_string( FILTER_PROPERTY_END_DAY, date( 'd' ) ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_END_YEAR] ) ) { $p_filter_arr[FILTER_PROPERTY_END_YEAR] = gpc_get_string( FILTER_PROPERTY_END_YEAR, date( 'Y' ) ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_SEARCH] ) ) { $p_filter_arr[FILTER_PROPERTY_SEARCH] = ''; } if( !isset( $p_filter_arr[FILTER_PROPERTY_FILTER_BY_DATE] ) ) { $p_filter_arr[FILTER_PROPERTY_FILTER_BY_DATE] = gpc_get_bool( FILTER_PROPERTY_FILTER_BY_DATE, false ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_VIEW_STATE] ) ) { $p_filter_arr[FILTER_PROPERTY_VIEW_STATE] = gpc_get( FILTER_PROPERTY_VIEW_STATE, '' ); } else if( filter_field_is_any( $p_filter_arr[FILTER_PROPERTY_VIEW_STATE] ) ) { $p_filter_arr[FILTER_PROPERTY_VIEW_STATE] = META_FILTER_ANY; } if( !isset( $p_filter_arr[FILTER_PROPERTY_RELATIONSHIP_TYPE] ) ) { $p_filter_arr[FILTER_PROPERTY_RELATIONSHIP_TYPE] = gpc_get_int( FILTER_PROPERTY_RELATIONSHIP_TYPE, -1 ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_RELATIONSHIP_BUG] ) ) { $p_filter_arr[FILTER_PROPERTY_RELATIONSHIP_BUG] = gpc_get_int( FILTER_PROPERTY_RELATIONSHIP_BUG, 0 ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_TARGET_VERSION] ) ) { $p_filter_arr[FILTER_PROPERTY_TARGET_VERSION] = META_FILTER_ANY; } if( !isset( $p_filter_arr[FILTER_PROPERTY_TAG_STRING] ) ) { $p_filter_arr[FILTER_PROPERTY_TAG_STRING] = gpc_get_string( FILTER_PROPERTY_TAG_STRING, '' ); } if( !isset( $p_filter_arr[FILTER_PROPERTY_TAG_SELECT] ) ) { $p_filter_arr[FILTER_PROPERTY_TAG_SELECT] = gpc_get_string( FILTER_PROPERTY_TAG_SELECT, '' ); } # initialize plugin filters $t_plugin_filters = filter_get_plugin_filters(); foreach( $t_plugin_filters as $t_field_name => $t_filter_object ) { if( !isset( $p_filter_arr[ $t_field_name ] ) ) { switch( $t_filter_object->type ) { case FILTER_TYPE_STRING: $p_filter_arr[ $t_field_name ] = gpc_get_string( $t_field_name, $t_filter_object->default ); break; case FILTER_TYPE_INT: $p_filter_arr[ $t_field_name ] = gpc_get_int( $t_field_name, (int)$t_filter_object->default ); break; case FILTER_TYPE_BOOLEAN: $p_filter_arr[ $t_field_name ] = gpc_get_bool( $t_field_name, (bool)$t_filter_object->default ); break; case FILTER_TYPE_MULTI_STRING: $p_filter_arr[ $t_field_name ] = gpc_get_string_array( $t_field_name, array( 0 => META_FILTER_ANY ) ); break; case FILTER_TYPE_MULTI_INT: $p_filter_arr[ $t_field_name ] = gpc_get_int_array( $t_field_name, array( 0 => META_FILTER_ANY ) ); break; default: $p_filter_arr[ $t_field_name ] = META_FILTER_ANY; } } if ( ! $t_filter_object->validate( $p_filter_arr[ $t_field_name ] ) ) { $p_filter_arr[ $t_field_name ] = $t_filter_object->default; } } $t_custom_fields = custom_field_get_ids(); # @@@ (thraxisp) This should really be the linked ids, but we don't know the project $f_custom_fields_data = array(); if( is_array( $t_custom_fields ) && ( count( $t_custom_fields ) > 0 ) ) { foreach( $t_custom_fields as $t_cfid ) { if( is_array( gpc_get( 'custom_field_' . $t_cfid, null ) ) ) { $f_custom_fields_data[$t_cfid] = gpc_get_string_array( 'custom_field_' . $t_cfid, META_FILTER_ANY ); } else { $f_custom_fields_data[$t_cfid] = gpc_get_string( 'custom_field_' . $t_cfid, META_FILTER_ANY ); $f_custom_fields_data[$t_cfid] = array( $f_custom_fields_data[$t_cfid], ); } } } # validate sorting $t_fields = helper_get_columns_to_view(); $t_n_fields = count( $t_fields ); for( $i = 0;$i < $t_n_fields;$i++ ) { if( isset( $t_fields[$i] ) && in_array( $t_fields[$i], array( 'selection', 'edit', 'bugnotes_count', 'attachment' ) ) ) { unset( $t_fields[$i] ); } } $t_sort_fields = explode( ',', $p_filter_arr['sort'] ); $t_dir_fields = explode( ',', $p_filter_arr['dir'] ); for( $i = 0;$i < 2;$i++ ) { if( isset( $t_sort_fields[$i] ) ) { $t_drop = false; $t_sort = $t_sort_fields[$i]; if( strpos( $t_sort, 'custom_' ) === 0 ) { if( false === custom_field_get_id_from_name( utf8_substr( $t_sort, utf8_strlen( 'custom_' ) ) ) ) { $t_drop = true; } } else { if( !in_array( $t_sort, $t_fields ) ) { $t_drop = true; } } if( !in_array( $t_dir_fields[$i], array( "ASC", "DESC" ) ) ) { $t_drop = true; } if( $t_drop ) { unset( $t_sort_fields[$i] ); unset( $t_dir_fields[$i] ); } } } if( count( $t_sort_fields ) > 0 ) { $p_filter_arr['sort'] = implode( ',', $t_sort_fields ); $p_filter_arr['dir'] = implode( ',', $t_dir_fields ); } else { $p_filter_arr['sort'] = "last_updated"; $p_filter_arr['dir'] = "DESC"; } # validate or filter junk from other fields $t_multi_select_list = array( FILTER_PROPERTY_CATEGORY_ID => 'string', FILTER_PROPERTY_SEVERITY => 'int', FILTER_PROPERTY_STATUS => 'int', FILTER_PROPERTY_REPORTER_ID => 'int', FILTER_PROPERTY_HANDLER_ID => 'int', FILTER_PROPERTY_NOTE_USER_ID => 'int', FILTER_PROPERTY_RESOLUTION => 'int', FILTER_PROPERTY_PRIORITY => 'int', FILTER_PROPERTY_BUILD => 'string', FILTER_PROPERTY_VERSION => 'string', FILTER_PROPERTY_HIDE_STATUS => 'int', FILTER_PROPERTY_FIXED_IN_VERSION => 'string', FILTER_PROPERTY_TARGET_VERSION => 'string', FILTER_PROPERTY_MONITOR_USER_ID => 'int', FILTER_PROPERTY_PROFILE_ID => 'int', ); foreach( $t_multi_select_list as $t_multi_field_name => $t_multi_field_type ) { if( !isset( $p_filter_arr[$t_multi_field_name] ) ) { if( FILTER_PROPERTY_HIDE_STATUS == $t_multi_field_name ) { $p_filter_arr[$t_multi_field_name] = array( config_get( 'hide_status_default' ), ); } else if( 'custom_fields' == $t_multi_field_name ) { $p_filter_arr[$t_multi_field_name] = array( $f_custom_fields_data, ); } else { $p_filter_arr[$t_multi_field_name] = array( META_FILTER_ANY, ); } } else { if( !is_array( $p_filter_arr[$t_multi_field_name] ) ) { $p_filter_arr[$t_multi_field_name] = array( $p_filter_arr[$t_multi_field_name], ); } $t_checked_array = array(); foreach( $p_filter_arr[$t_multi_field_name] as $t_filter_value ) { $t_filter_value = stripslashes( $t_filter_value ); if(( $t_filter_value === 'any' ) || ( $t_filter_value === '[any]' ) ) { $t_filter_value = META_FILTER_ANY; } if(( $t_filter_value === 'none' ) || ( $t_filter_value === '[none]' ) ) { $t_filter_value = META_FILTER_NONE; } if( 'string' == $t_multi_field_type ) { $t_checked_array[] = db_prepare_string( $t_filter_value ); } else if( 'int' == $t_multi_field_type ) { $t_checked_array[] = db_prepare_int( $t_filter_value ); } else if( 'array' == $t_multi_field_type ) { $t_checked_array[] = $t_filter_value; } } $p_filter_arr[$t_multi_field_name] = $t_checked_array; } } if( is_array( $t_custom_fields ) && ( count( $t_custom_fields ) > 0 ) ) { foreach( $t_custom_fields as $t_cfid ) { if( !isset( $p_filter_arr['custom_fields'][$t_cfid] ) ) { $p_filter_arr['custom_fields'][$t_cfid] = array( META_FILTER_ANY, ); } else { if( !is_array( $p_filter_arr['custom_fields'][$t_cfid] ) ) { $p_filter_arr['custom_fields'][$t_cfid] = array( $p_filter_arr['custom_fields'][$t_cfid], ); } $t_checked_array = array(); foreach( $p_filter_arr['custom_fields'][$t_cfid] as $t_filter_value ) { $t_filter_value = stripslashes( $t_filter_value ); if(( $t_filter_value === 'any' ) || ( $t_filter_value === '[any]' ) ) { $t_filter_value = META_FILTER_ANY; } $t_checked_array[] = db_prepare_string( $t_filter_value ); } $p_filter_arr['custom_fields'][$t_cfid] = $t_checked_array; } } } # all of our filter values are now guaranteed to be there, and correct. return $p_filter_arr; } /** * Get the standard filter that is to be used when no filter was previously saved. * When creating specific filters, this can be used as a basis for the filter, where * specific entries can be overridden. * @return mixed */ function filter_get_default() { $t_hide_status_default = config_get( 'hide_status_default' ); $t_default_show_changed = config_get( 'default_show_changed' ); $t_filter = array( FILTER_PROPERTY_CATEGORY_ID => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_SEVERITY => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_STATUS => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_HIGHLIGHT_CHANGED => $t_default_show_changed, FILTER_PROPERTY_REPORTER_ID => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_HANDLER_ID => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_PROJECT_ID => Array( '0' => META_FILTER_CURRENT, ), FILTER_PROPERTY_RESOLUTION => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_BUILD => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_VERSION => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_HIDE_STATUS => Array( '0' => $t_hide_status_default, ), FILTER_PROPERTY_MONITOR_USER_ID => Array( '0' => META_FILTER_ANY, ), FILTER_PROPERTY_SORT_FIELD_NAME => 'last_updated', FILTER_PROPERTY_SORT_DIRECTION => 'DESC', FILTER_PROPERTY_ISSUES_PER_PAGE => config_get( 'default_limit_view' ), ); return filter_ensure_valid_filter( $t_filter ); } /** * Deserialize filter string * @param string $p_serialized_filter * @return mixed $t_filter array * @see filter_ensure_valid_filter */ function filter_deserialize( $p_serialized_filter ) { if( is_blank( $p_serialized_filter ) ) { return false; } # check to see if new cookie is needed $t_setting_arr = explode( '#', $p_serialized_filter, 2 ); if(( $t_setting_arr[0] == 'v1' ) || ( $t_setting_arr[0] == 'v2' ) || ( $t_setting_arr[0] == 'v3' ) || ( $t_setting_arr[0] == 'v4' ) ) { # these versions can't be salvaged, they are too old to update return false; } # We shouldn't need to do this anymore, as filters from v5 onwards should cope with changing # filter indices dynamically $t_filter_array = array(); if( isset( $t_setting_arr[1] ) ) { $t_filter_array = unserialize( $t_setting_arr[1] ); } else { return false; } if( $t_filter_array['_version'] != config_get( 'cookie_version' ) ) { # if the version is not new enough, update it using defaults return filter_ensure_valid_filter( $t_filter_array ); } return $t_filter_array; } /** * Check if the filter cookie exists and is of the correct version. * @return bool */ function filter_is_cookie_valid() { $t_view_all_cookie_id = gpc_get_cookie( config_get( 'view_all_cookie' ), '' ); $t_view_all_cookie = filter_db_get_filter( $t_view_all_cookie_id ); # check to see if the cookie does not exist if( is_blank( $t_view_all_cookie ) ) { return false; } # check to see if new cookie is needed $t_setting_arr = explode( '#', $t_view_all_cookie, 2 ); if(( $t_setting_arr[0] == 'v1' ) || ( $t_setting_arr[0] == 'v2' ) || ( $t_setting_arr[0] == 'v3' ) || ( $t_setting_arr[0] == 'v4' ) ) { return false; } # We shouldn't need to do this anymore, as filters from v5 onwards should cope with changing # filter indices dynamically $t_filter_cookie_arr = array(); if( isset( $t_setting_arr[1] ) ) { $t_filter_cookie_arr = unserialize( $t_setting_arr[1] ); } else { return false; } if( $t_filter_cookie_arr['_version'] != config_get( 'cookie_version' ) ) { return false; } return true; } /** * Get the array fields specified by $p_filter_id * using the cached row if it's available * @param int $p_filter_id * @return mixed a filter row */ function filter_get_row( $p_filter_id ) { return filter_cache_row( $p_filter_id ); } /** * Get the value of the filter field specified by filter id and field name * @param int $p_filter_id * @param string $p_field_name * @return string */ function filter_get_field( $p_filter_id, $p_field_name ) { $row = filter_get_row( $p_filter_id ); if( isset( $row[$p_field_name] ) ) { return $row[$p_field_name]; } else { error_parameters( $p_field_name ); trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING ); return ''; } } /** * Add sort parameters to the query clauses * @param array $p_filter * @param bool $p_show_sticky * @param array $p_query_clauses * @return array $p_query_clauses */ function filter_get_query_sort_data( &$p_filter, $p_show_sticky, $p_query_clauses ) { $t_bug_table = db_get_table( 'bug' ); $t_custom_field_string_table = db_get_table( 'custom_field_string' ); # if sort is blank then default the sort and direction. This is to fix the # symptoms of #3953. Note that even if the main problem is fixed, we may # have to keep this code for a while to handle filters saved with this blank field. if( is_blank( $p_filter[FILTER_PROPERTY_SORT_FIELD_NAME] ) ) { $p_filter[FILTER_PROPERTY_SORT_FIELD_NAME] = 'last_updated'; $p_filter[FILTER_PROPERTY_SORT_DIRECTION] = 'DESC'; } $p_query_clauses['order'] = array(); $t_sort_fields = explode( ',', $p_filter[FILTER_PROPERTY_SORT_FIELD_NAME] ); $t_dir_fields = explode( ',', $p_filter[FILTER_PROPERTY_SORT_DIRECTION] ); $t_plugin_columns = columns_get_plugin_columns(); if ( gpc_string_to_bool( $p_filter[FILTER_PROPERTY_STICKY] ) && ( NULL !== $p_show_sticky ) ) { $p_query_clauses['order'][] = "$t_bug_table.sticky DESC"; } $t_count = count( $t_sort_fields ); for( $i = 0;$i < $t_count;$i++ ) { $c_sort = db_prepare_string( $t_sort_fields[$i] ); $c_dir = 'DESC' == $t_dir_fields[$i] ? 'DESC' : 'ASC'; if( !in_array( $t_sort_fields[$i], array_slice( $t_sort_fields, $i + 1 ) ) ) { # if sorting by a custom field if( strpos( $c_sort, 'custom_' ) === 0 ) { $t_custom_field = utf8_substr( $c_sort, utf8_strlen( 'custom_' ) ); $t_custom_field_id = custom_field_get_id_from_name( $t_custom_field ); $t_def = custom_field_get_definition( $t_custom_field_id ); $t_value_field = ( $t_def['type'] == CUSTOM_FIELD_TYPE_TEXTAREA ? 'text' : 'value' ); $c_cf_alias = str_replace( ' ', '_', $t_custom_field ); $t_cf_table_alias = $t_custom_field_string_table . '_' . $t_custom_field_id; $t_cf_select = "$t_cf_table_alias.$t_value_field $c_cf_alias"; # check to be sure this field wasn't already added to the query. if( !in_array( $t_cf_select, $p_query_clauses['select'] ) ) { $p_query_clauses['select'][] = $t_cf_select; $p_query_clauses['join'][] = "LEFT JOIN $t_custom_field_string_table $t_cf_table_alias ON $t_bug_table.id = $t_cf_table_alias.bug_id AND $t_cf_table_alias.field_id = $t_custom_field_id"; } $p_query_clauses['order'][] = "$c_cf_alias $c_dir"; # if sorting by plugin columns } else if ( isset( $t_plugin_columns[ $t_sort_fields[$i] ] ) ) { $t_column_object = $t_plugin_columns[ $t_sort_fields[$i] ]; if ( $t_column_object->sortable ) { $t_clauses = $t_column_object->sortquery( $c_dir ); if ( is_array( $t_clauses ) ) { if ( isset( $t_clauses['join'] ) ) { $p_query_clauses['join'][] = $t_clauses['join']; } if ( isset( $t_clauses['order'] ) ) { $p_query_clauses['order'][] = $t_clauses['order']; } } } # standard column } else { if ( 'last_updated' == $c_sort ) { $c_sort = "last_updated"; } $p_query_clauses['order'][] = "$t_bug_table.$c_sort $c_dir"; } } } # add basic sorting if necessary if( !in_array( 'last_updated', $t_sort_fields ) ) { $p_query_clauses['order'][] = "$t_bug_table.last_updated DESC"; } if( !in_array( 'date_submitted', $t_sort_fields ) ) { $p_query_clauses['order'][] = "$t_bug_table.date_submitted DESC"; } return $p_query_clauses; } /** * Remove any duplicate values in certain elements of query_clauses * Do not loop over query clauses as some keys may contain valid duplicate values. * We basically want unique values for just the base query elements select, from, and join * 'where' and 'where_values' key should not have duplicates as that is handled earlier and applying * array_unique here could cause problems with the query. * @param $p_query_clauses * @return $p_query_clauses */ function filter_unique_query_clauses( $p_query_clauses ) { $p_query_clauses['select'] = array_unique( $p_query_clauses['select'] ); $p_query_clauses['from'] = array_unique( $p_query_clauses['from'] ); $p_query_clauses['join'] = array_unique( $p_query_clauses['join'] ); return $p_query_clauses; } /** * Build a query with the query clauses array, query for bug count and return the result * @param array $p_query_clauses * @return int */ function filter_get_bug_count( $p_query_clauses ) { $t_bug_table = db_get_table( 'bug' ); $p_query_clauses = filter_unique_query_clauses( $p_query_clauses ); $t_select_string = "SELECT Count( DISTINCT $t_bug_table.id ) as idcnt "; $t_from_string = " FROM " . implode( ', ', $p_query_clauses['from'] ); $t_join_string = (( count( $p_query_clauses['join'] ) > 0 ) ? implode( ' ', $p_query_clauses['join'] ) : '' ); $t_where_string = (( count( $p_query_clauses['where'] ) > 0 ) ? 'WHERE ' . implode( ' AND ', $p_query_clauses['where'] ) : '' ); $t_result = db_query_bound( "$t_select_string $t_from_string $t_join_string $t_where_string", $p_query_clauses['where_values'] ); return db_result( $t_result ); } /** * @todo Had to make all these parameters required because we can't use * call-time pass by reference anymore. I really preferred not having * to pass all the params in if you didn't want to, but I wanted to get * rid of the errors for now. If we can think of a better way later * (maybe return an object) that would be great. * * @param int $p_page_number the page you want to see (set to the actual page on return) * @param int $p_per_page the number of bugs to see per page (set to actual on return) * -1 indicates you want to see all bugs * null indicates you want to use the value specified in the filter * @param int $p_page_count you don't need to give a value here, the number of pages will be stored here on return * @param int $p_bug_count you don't need to give a value here, the number of bugs will be stored here on return * @param mixed $p_custom_filter Filter to use. * @param int $p_project_id project id to use in filtering. * @param int $p_user_id user id to use as current user when filtering. * @param bool $p_show_sticky get sticky issues only. */ function filter_get_bug_rows( &$p_page_number, &$p_per_page, &$p_page_count, &$p_bug_count, $p_custom_filter = null, $p_project_id = null, $p_user_id = null, $p_show_sticky = null ) { log_event( LOG_FILTERING, 'START NEW FILTER QUERY' ); $t_bug_table = db_get_table( 'bug' ); $t_bug_text_table = db_get_table( 'bug_text' ); $t_bugnote_table = db_get_table( 'bugnote' ); $t_category_table = db_get_table( 'category' ); $t_custom_field_string_table = db_get_table( 'custom_field_string' ); $t_bugnote_text_table = db_get_table( 'bugnote_text' ); $t_project_table = db_get_table( 'project' ); $t_bug_monitor_table = db_get_table( 'bug_monitor' ); $t_limit_reporters = config_get( 'limit_reporters' ); $t_bug_relationship_table = db_get_table( 'bug_relationship' ); $t_report_bug_threshold = config_get( 'report_bug_threshold' ); $t_where_param_count = 0; $t_current_user_id = auth_get_current_user_id(); if( null === $p_user_id ) { $t_user_id = $t_current_user_id; } else { $t_user_id = $p_user_id; } $c_user_id = db_prepare_int( $t_user_id ); if( null === $p_project_id ) { # @@@ If project_id is not specified, then use the project id(s) in the filter if set, otherwise, use current project. $t_project_id = helper_get_current_project(); } else { $t_project_id = $p_project_id; } if( $p_custom_filter === null ) { # Prefer current_user_get_bug_filter() over user_get_filter() when applicable since it supports # cookies set by previous version of the code. if( $t_user_id == $t_current_user_id ) { $t_filter = current_user_get_bug_filter(); } else { $t_filter = user_get_bug_filter( $t_user_id, $t_project_id ); } } else { $t_filter = $p_custom_filter; } $t_filter = filter_ensure_valid_filter( $t_filter ); if( false === $t_filter ) { return false; # signify a need to create a cookie # @@@ error instead? } $t_view_type = $t_filter['_view_type']; $t_where_clauses = array( "$t_project_table.enabled = " . db_param(), "$t_project_table.id = $t_bug_table.project_id", ); $t_where_params = array( 1, ); $t_select_clauses = array( "$t_bug_table.*", "$t_bug_table.last_updated", "$t_bug_table.date_submitted", ); $t_join_clauses = array(); $t_from_clauses = array(); // normalize the project filtering into an array $t_project_ids if( 'simple' == $t_view_type ) { log_event( LOG_FILTERING, 'Simple Filter' ); $t_project_ids = array( $t_project_id, ); $t_include_sub_projects = true; } else { log_event( LOG_FILTERING, 'Advanced Filter' ); if( !is_array( $t_filter[FILTER_PROPERTY_PROJECT_ID] ) ) { $t_project_ids = array( db_prepare_int( $t_filter[FILTER_PROPERTY_PROJECT_ID] ), ); } else { $t_project_ids = array_map( 'db_prepare_int', $t_filter[FILTER_PROPERTY_PROJECT_ID] ); } $t_include_sub_projects = (( count( $t_project_ids ) == 1 ) && ( ( $t_project_ids[0] == META_FILTER_CURRENT ) || ( $t_project_ids[0] == ALL_PROJECTS ) ) ); } log_event( LOG_FILTERING, 'project_ids = @P' . implode( ', @P', $t_project_ids ) ); log_event( LOG_FILTERING, 'include sub-projects = ' . ( $t_include_sub_projects ? '1' : '0' ) ); // if the array has ALL_PROJECTS, then reset the array to only contain ALL_PROJECTS. // replace META_FILTER_CURRENT with the actualy current project id. $t_all_projects_found = false; $t_new_project_ids = array(); foreach( $t_project_ids as $t_pid ) { if( $t_pid == META_FILTER_CURRENT ) { $t_pid = $t_project_id; } if( $t_pid == ALL_PROJECTS ) { $t_all_projects_found = true; log_event( LOG_FILTERING, 'all projects selected' ); break; } // filter out inaccessible projects. if( !access_has_project_level( VIEWER, $t_pid, $t_user_id ) ) { continue; } $t_new_project_ids[] = $t_pid; } $t_projects_query_required = true; if( $t_all_projects_found ) { if( user_is_administrator( $t_user_id ) ) { log_event( LOG_FILTERING, 'all projects + administrator, hence no project filter.' ); $t_projects_query_required = false; } else { $t_project_ids = user_get_accessible_projects( $t_user_id ); } } else { $t_project_ids = $t_new_project_ids; } if( $t_projects_query_required ) { // expand project ids to include sub-projects if( $t_include_sub_projects ) { $t_top_project_ids = $t_project_ids; foreach( $t_top_project_ids as $t_pid ) { log_event( LOG_FILTERING, 'Getting sub-projects for project id @P' . $t_pid ); $t_project_ids = array_merge( $t_project_ids, user_get_all_accessible_subprojects( $t_user_id, $t_pid ) ); } $t_project_ids = array_unique( $t_project_ids ); } // if no projects are accessible, then return an empty array. if( count( $t_project_ids ) == 0 ) { log_event( LOG_FILTERING, 'no accessible projects' ); return array(); } log_event( LOG_FILTERING, 'project_ids after including sub-projects = @P' . implode( ', @P', $t_project_ids ) ); // this array is to be populated with project ids for which we only want to show public issues. This is due to the limited // access of the current user. $t_public_only_project_ids = array(); // this array is populated with project ids that the current user has full access to. $t_private_and_public_project_ids = array(); $t_access_required_to_view_private_bugs = config_get( 'private_bug_threshold' ); foreach( $t_project_ids as $t_pid ) { if( access_has_project_level( $t_access_required_to_view_private_bugs, $t_pid, $t_user_id ) ) { $t_private_and_public_project_ids[] = $t_pid; } else { $t_public_only_project_ids[] = $t_pid; } } log_event( LOG_FILTERING, 'project_ids (with public/private access) = @P' . implode( ', @P', $t_private_and_public_project_ids ) ); log_event( LOG_FILTERING, 'project_ids (with public access) = @P' . implode( ', @P', $t_public_only_project_ids ) ); $t_count_private_and_public_project_ids = count( $t_private_and_public_project_ids ); if( $t_count_private_and_public_project_ids == 1 ) { $t_private_and_public_query = "( $t_bug_table.project_id = " . $t_private_and_public_project_ids[0] . " )"; } else if( $t_count_private_and_public_project_ids > 1 ) { $t_private_and_public_query = "( $t_bug_table.project_id in (" . implode( ', ', $t_private_and_public_project_ids ) . ") )"; } else { $t_private_and_public_query = null; } $t_count_public_only_project_ids = count( $t_public_only_project_ids ); $t_public_view_state_check = "( ( $t_bug_table.view_state = " . VS_PUBLIC . " ) OR ( $t_bug_table.reporter_id = $t_user_id ) )"; if( $t_count_public_only_project_ids == 1 ) { $t_public_only_query = "( ( $t_bug_table.project_id = " . $t_public_only_project_ids[0] . " ) AND $t_public_view_state_check )"; } else if( $t_count_public_only_project_ids > 1 ) { $t_public_only_query = "( ( $t_bug_table.project_id in (" . implode( ', ', $t_public_only_project_ids ) . ") ) AND $t_public_view_state_check )"; } else { $t_public_only_query = null; } // both queries can't be null, so we either have one of them or both. if( $t_private_and_public_query === null ) { $t_project_query = $t_public_only_query; } else if( $t_public_only_query === null ) { $t_project_query = $t_private_and_public_query; } else { $t_project_query = "( $t_public_only_query OR $t_private_and_public_query )"; } log_event( LOG_FILTERING, 'project query = ' . $t_project_query ); array_push( $t_where_clauses, $t_project_query ); } # view state $t_view_state = db_prepare_int( $t_filter[FILTER_PROPERTY_VIEW_STATE] ); if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_VIEW_STATE] ) ) { $t_view_state_query = "($t_bug_table.view_state=" . db_param() . ')'; log_event( LOG_FILTERING, 'view_state query = ' . $t_view_state_query ); $t_where_params[] = $t_view_state; array_push( $t_where_clauses, $t_view_state_query ); } else { log_event( LOG_FILTERING, 'no view_state query' ); } # reporter if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_REPORTER_ID] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_REPORTER_ID] as $t_filter_member ) { if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, "0" ); } else { $c_reporter_id = db_prepare_int( $t_filter_member ); if( filter_field_is_myself( $c_reporter_id ) ) { array_push( $t_clauses, $c_user_id ); } else { array_push( $t_clauses, $c_reporter_id ); } } } if( 1 < count( $t_clauses ) ) { $t_reporter_query = "( $t_bug_table.reporter_id in (" . implode( ', ', $t_clauses ) . ") )"; } else { $t_reporter_query = "( $t_bug_table.reporter_id=$t_clauses[0] )"; } log_event( LOG_FILTERING, 'reporter query = ' . $t_reporter_query ); array_push( $t_where_clauses, $t_reporter_query ); } else { log_event( LOG_FILTERING, 'no reporter query' ); } # limit reporter # @@@ thraxisp - access_has_project_level checks greater than or equal to, # this assumed that there aren't any holes above REPORTER where the limit would apply # if(( ON === $t_limit_reporters ) && ( !access_has_project_level( REPORTER + 1, $t_project_id, $t_user_id ) ) ) { $c_reporter_id = $c_user_id; $t_where_params[] = $c_reporter_id; array_push( $t_where_clauses, "($t_bug_table.reporter_id=" . db_param() . ')' ); } # handler if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_HANDLER_ID] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_HANDLER_ID] as $t_filter_member ) { if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, 0 ); } else { $c_handler_id = db_prepare_int( $t_filter_member ); if( filter_field_is_myself( $c_handler_id ) ) { array_push( $t_clauses, $c_user_id ); } else { array_push( $t_clauses, $c_handler_id ); } } } if( 1 < count( $t_clauses ) ) { $t_handler_query = "( $t_bug_table.handler_id in (" . implode( ', ', $t_clauses ) . ") )"; } else { $t_handler_query = "( $t_bug_table.handler_id=$t_clauses[0] )"; } log_event( LOG_FILTERING, 'handler query = ' . $t_handler_query ); array_push( $t_where_clauses, $t_handler_query ); } else { log_event( LOG_FILTERING, 'no handler query' ); } # category if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_CATEGORY_ID] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_CATEGORY_ID] as $t_filter_member ) { if( !filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, $t_filter_member ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.category_id in ( SELECT id FROM $t_category_table WHERE name in (" . implode( ', ', $t_where_tmp ) . ") ) )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.category_id in ( SELECT id FROM $t_category_table WHERE name=" . db_param() . ") )" ); } } # severity if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_SEVERITY] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_SEVERITY] as $t_filter_member ) { $c_show_severity = db_prepare_int( $t_filter_member ); array_push( $t_clauses, $c_show_severity ); } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.severity in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.severity=" . db_param() . " )" ); } } # show / hide status # take a list of all available statuses then remove the ones that we want hidden, then make sure # the ones we want shown are still available $t_desired_statuses = array(); $t_available_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) ); if( 'simple' == $t_filter['_view_type'] ) { # simple filtering: if showing any, restrict by the hide status value, otherwise ignore the hide $t_any_found = false; $t_this_status = $t_filter[FILTER_PROPERTY_STATUS][0]; $t_this_hide_status = $t_filter[FILTER_PROPERTY_HIDE_STATUS][0]; if( filter_field_is_any( $t_this_status ) ) { foreach( $t_available_statuses as $t_this_available_status ) { if( $t_this_hide_status > $t_this_available_status ) { $t_desired_statuses[] = $t_this_available_status; } } } else { $t_desired_statuses[] = $t_this_status; } } else { # advanced filtering: ignore the hide if( filter_field_is_any( $t_filter[FILTER_PROPERTY_STATUS] ) ) { $t_desired_statuses = array(); } else { foreach( $t_filter[FILTER_PROPERTY_STATUS] as $t_this_status ) { $t_desired_statuses[] = $t_this_status; } } } if( count( $t_desired_statuses ) > 0 ) { $t_clauses = array(); foreach( $t_desired_statuses as $t_filter_member ) { $c_show_status = db_prepare_int( $t_filter_member ); array_push( $t_clauses, $c_show_status ); } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.status in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.status=" . db_param() . " )" ); } } # resolution if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_RESOLUTION] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_RESOLUTION] as $t_filter_member ) { $c_show_resolution = db_prepare_int( $t_filter_member ); array_push( $t_clauses, $c_show_resolution ); } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.resolution in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.resolution=" . db_param() . " )" ); } } # priority if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_PRIORITY] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_PRIORITY] as $t_filter_member ) { $c_show_priority = db_prepare_int( $t_filter_member ); array_push( $t_clauses, $c_show_priority ); } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.priority in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.priority=" . db_param() . " )" ); } } # product build if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_BUILD] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_BUILD] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, '' ); } else { $c_show_build = db_prepare_string( $t_filter_member ); array_push( $t_clauses, $c_show_build ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.build in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.build=" . db_param() . " )" ); } } # product version if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_VERSION] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_VERSION] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, '' ); } else { $c_show_version = db_prepare_string( $t_filter_member ); array_push( $t_clauses, $c_show_version ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.version in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.version=" . db_param() . " )" ); } } # profile if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_PROFILE_ID] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_PROFILE_ID] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, "0" ); } else { $c_show_profile = db_prepare_int( $t_filter_member ); array_push( $t_clauses, "$c_show_profile" ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.profile_id in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.profile_id=" . db_param() . " )" ); } } # platform if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_PLATFORM] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_PLATFORM] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, '' ); } else { $c_platform = db_prepare_string( $t_filter_member ); array_push( $t_clauses, $c_platform ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.platform in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.platform = " . db_param() . " )" ); } } # os if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_OS] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_OS] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, '' ); } else { $c_os = db_prepare_string( $t_filter_member ); array_push( $t_clauses, $c_os ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.os in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.os = " . db_param() . " )" ); } } # os_build if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_OS_BUILD] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_OS_BUILD] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, '' ); } else { $c_os_build = db_prepare_string( $t_filter_member ); array_push( $t_clauses, $c_os_build ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.os_build in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.os_build = " . db_param() . " )" ); } } # date filter if(( 'on' == $t_filter[FILTER_PROPERTY_FILTER_BY_DATE] ) && is_numeric( $t_filter[FILTER_PROPERTY_START_MONTH] ) && is_numeric( $t_filter[FILTER_PROPERTY_START_DAY] ) && is_numeric( $t_filter[FILTER_PROPERTY_START_YEAR] ) && is_numeric( $t_filter[FILTER_PROPERTY_END_MONTH] ) && is_numeric( $t_filter[FILTER_PROPERTY_END_DAY] ) && is_numeric( $t_filter[FILTER_PROPERTY_END_YEAR] ) ) { $t_start_string = $t_filter[FILTER_PROPERTY_START_YEAR] . "-" . $t_filter[FILTER_PROPERTY_START_MONTH] . "-" . $t_filter[FILTER_PROPERTY_START_DAY] . " 00:00:00"; $t_end_string = $t_filter[FILTER_PROPERTY_END_YEAR] . "-" . $t_filter[FILTER_PROPERTY_END_MONTH] . "-" . $t_filter[FILTER_PROPERTY_END_DAY] . " 23:59:59"; $t_where_params[] = strtotime( $t_start_string ); $t_where_params[] = strtotime( $t_end_string ); array_push( $t_where_clauses, "($t_bug_table.date_submitted BETWEEN " . db_param() . " AND " . db_param() . " )" ); } # fixed in version if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_FIXED_IN_VERSION] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_FIXED_IN_VERSION] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, '' ); } else { $c_fixed_in_version = db_prepare_string( $t_filter_member ); array_push( $t_clauses, $c_fixed_in_version ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.fixed_in_version in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.fixed_in_version=" . db_param() . " )" ); } } # target version if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_TARGET_VERSION] ) ) { $t_clauses = array(); foreach( $t_filter[FILTER_PROPERTY_TARGET_VERSION] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { array_push( $t_clauses, '' ); } else { $c_target_version = db_prepare_string( $t_filter_member ); array_push( $t_clauses, $c_target_version ); } } # echo var_dump( $t_clauses ); exit; if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bug_table.target_version in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bug_table.target_version=" . db_param() . " )" ); } } # users monitoring a bug if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_MONITOR_USER_ID] ) ) { $t_clauses = array(); $t_table_name = 'user_monitor'; array_push( $t_join_clauses, "LEFT JOIN $t_bug_monitor_table $t_table_name ON $t_table_name.bug_id = $t_bug_table.id" ); foreach( $t_filter[FILTER_PROPERTY_MONITOR_USER_ID] as $t_filter_member ) { $c_user_monitor = db_prepare_int( $t_filter_member ); if( filter_field_is_myself( $c_user_monitor ) ) { array_push( $t_clauses, $c_user_id ); } else { array_push( $t_clauses, $c_user_monitor ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_table_name.user_id in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_table_name.user_id=" . db_param() . " )" ); } } # bug relationship $t_any_found = false; $c_rel_type = $t_filter[FILTER_PROPERTY_RELATIONSHIP_TYPE]; $c_rel_bug = $t_filter[FILTER_PROPERTY_RELATIONSHIP_BUG]; if( -1 == $c_rel_type || 0 == $c_rel_bug ) { $t_any_found = true; } if( !$t_any_found ) { # use the complementary type $t_comp_type = relationship_get_complementary_type( $c_rel_type ); $t_clauses = array(); $t_table_name = 'relationship'; array_push( $t_join_clauses, "LEFT JOIN $t_bug_relationship_table $t_table_name ON $t_table_name.destination_bug_id = $t_bug_table.id" ); array_push( $t_join_clauses, "LEFT JOIN $t_bug_relationship_table ${t_table_name}2 ON ${t_table_name}2.source_bug_id = $t_bug_table.id" ); // get reverse relationships $t_where_params[] = $t_comp_type; $t_where_params[] = $c_rel_bug; $t_where_params[] = $c_rel_type; $t_where_params[] = $c_rel_bug; array_push( $t_clauses, "($t_table_name.relationship_type=" . db_param() . " AND $t_table_name.source_bug_id=" . db_param() . ')' ); array_push( $t_clauses, "($t_table_name" . "2.relationship_type=" . db_param() . " AND $t_table_name" . "2.destination_bug_id=" . db_param() . ')' ); array_push( $t_where_clauses, '(' . implode( ' OR ', $t_clauses ) . ')' ); } # tags $c_tag_string = trim( $t_filter[FILTER_PROPERTY_TAG_STRING] ); $c_tag_select = trim( $t_filter[FILTER_PROPERTY_TAG_SELECT] ); if( is_blank( $c_tag_string ) && !is_blank( $c_tag_select ) && $c_tag_select != 0 ) { $t_tag = tag_get( $c_tag_select ); $c_tag_string = $t_tag['name']; } if( !is_blank( $c_tag_string ) ) { $t_tags = tag_parse_filters( $c_tag_string ); if( count( $t_tags ) ) { $t_tags_all = array(); $t_tags_any = array(); $t_tags_none = array(); foreach( $t_tags as $t_tag_row ) { switch( $t_tag_row['filter'] ) { case 1: $t_tags_all[] = $t_tag_row; break; case 0: $t_tags_any[] = $t_tag_row; break; case -1: $t_tags_none[] = $t_tag_row; break; } } if( 0 < $t_filter[FILTER_PROPERTY_TAG_SELECT] && tag_exists( $t_filter[FILTER_PROPERTY_TAG_SELECT] ) ) { $t_tags_any[] = tag_get( $t_filter[FILTER_PROPERTY_TAG_SELECT] ); } $t_bug_tag_table = db_get_table( 'bug_tag' ); if( count( $t_tags_all ) ) { $t_clauses = array(); foreach( $t_tags_all as $t_tag_row ) { array_push( $t_clauses, "$t_bug_table.id IN ( SELECT bug_id FROM $t_bug_tag_table WHERE $t_bug_tag_table.tag_id = $t_tag_row[id] )" ); } array_push( $t_where_clauses, '(' . implode( ' AND ', $t_clauses ) . ')' ); } if( count( $t_tags_any ) ) { $t_clauses = array(); foreach( $t_tags_any as $t_tag_row ) { array_push( $t_clauses, "$t_bug_tag_table.tag_id = $t_tag_row[id]" ); } array_push( $t_where_clauses, "$t_bug_table.id IN ( SELECT bug_id FROM $t_bug_tag_table WHERE ( " . implode( ' OR ', $t_clauses ) . ') )' ); } if( count( $t_tags_none ) ) { $t_clauses = array(); foreach( $t_tags_none as $t_tag_row ) { array_push( $t_clauses, "$t_bug_tag_table.tag_id = $t_tag_row[id]" ); } array_push( $t_where_clauses, "$t_bug_table.id NOT IN ( SELECT bug_id FROM $t_bug_tag_table WHERE ( " . implode( ' OR ', $t_clauses ) . ') )' ); } } } # note user id if( !filter_field_is_any( $t_filter[FILTER_PROPERTY_NOTE_USER_ID] ) ) { $t_bugnote_table_alias = 'mbnt'; $t_clauses = array(); array_push( $t_from_clauses, "$t_bugnote_table $t_bugnote_table_alias" ); array_push( $t_where_clauses, "( $t_bug_table.id = $t_bugnote_table_alias.bug_id )" ); foreach( $t_filter[FILTER_PROPERTY_NOTE_USER_ID] as $t_filter_member ) { $c_note_user_id = db_prepare_int( $t_filter_member ); if( filter_field_is_myself( $c_note_user_id ) ) { array_push( $t_clauses, $c_user_id ); } else { array_push( $t_clauses, $c_note_user_id ); } } if( 1 < count( $t_clauses ) ) { $t_where_tmp = array(); foreach( $t_clauses as $t_clause ) { $t_where_tmp[] = db_param(); $t_where_params[] = $t_clause; } array_push( $t_where_clauses, "( $t_bugnote_table_alias.reporter_id in (" . implode( ', ', $t_where_tmp ) . ") )" ); } else { $t_where_params[] = $t_clauses[0]; array_push( $t_where_clauses, "( $t_bugnote_table_alias.reporter_id=" . db_param() . " )" ); } } # plugin filters $t_plugin_filters = filter_get_plugin_filters(); foreach( $t_plugin_filters as $t_field_name => $t_filter_object ) { if ( !filter_field_is_any( $t_filter[ $t_field_name ] ) || $t_filter_object->type == FILTER_TYPE_BOOLEAN ) { $t_filter_query = $t_filter_object->query( $t_filter[ $t_field_name ] ); if ( is_array( $t_filter_query ) ) { if ( isset( $t_filter_query['join'] ) ) { array_push( $t_join_clauses, $t_filter_query['join'] ); } if ( isset( $t_filter_query['where'] ) ) { array_push( $t_where_clauses, $t_filter_query['where'] ); } if ( isset( $t_filter_query['params'] ) && is_array( $t_filter_query['params'] ) ) { $t_where_params = array_merge( $t_where_params, $t_filter_query['params'] ); } } } } # custom field filters if( ON == config_get( 'filter_by_custom_fields' ) ) { # custom field filtering # @@@ At the moment this gets the linked fields relating to the current project # It should get the ones relating to the project in the filter or all projects # if multiple projects. $t_custom_fields = custom_field_get_linked_ids( $t_project_id ); foreach( $t_custom_fields as $t_cfid ) { $t_field_info = custom_field_cache_row( $t_cfid, true ); if( !$t_field_info['filter_by'] ) { continue; # skip this custom field it shouldn't be filterable } $t_custom_where_clause = ''; # Ignore all custom filters that are not set, or that are set to '' or "any" if( !filter_field_is_any( $t_filter['custom_fields'][$t_cfid] ) ) { $t_def = custom_field_get_definition( $t_cfid ); $t_table_name = $t_custom_field_string_table . '_' . $t_cfid; # We need to filter each joined table or the result query will explode in dimensions # Each custom field will result in a exponential growth like Number_of_Issues^Number_of_Custom_Fields # and only after this process ends (if it is able to) the result query will be filtered # by the WHERE clause and by the DISTINCT clause $t_cf_join_clause = "LEFT JOIN $t_custom_field_string_table $t_table_name ON $t_bug_table.id = $t_table_name.bug_id AND $t_table_name.field_id = $t_cfid"; if( $t_def['type'] == CUSTOM_FIELD_TYPE_DATE ) { switch( $t_filter['custom_fields'][$t_cfid][0] ) { case CUSTOM_FIELD_DATE_ANY: break; case CUSTOM_FIELD_DATE_NONE: array_push( $t_join_clauses, $t_cf_join_clause ); $t_custom_where_clause = '(( ' . $t_table_name . '.bug_id is null) OR ( ' . $t_table_name . '.value = 0)'; break; case CUSTOM_FIELD_DATE_BEFORE: array_push( $t_join_clauses, $t_cf_join_clause ); $t_custom_where_clause = '(( ' . $t_table_name . '.value != 0 AND (' . $t_table_name . '.value+0) < ' . ( $t_filter['custom_fields'][$t_cfid][2] ) . ')'; break; case CUSTOM_FIELD_DATE_AFTER: array_push( $t_join_clauses, $t_cf_join_clause ); $t_custom_where_clause = '( (' . $t_table_name . '.value+0) > ' . ( $t_filter['custom_fields'][$t_cfid][1] + 1 ); break; default: array_push( $t_join_clauses, $t_cf_join_clause ); $t_custom_where_clause = '( (' . $t_table_name . '.value+0) BETWEEN ' . $t_filter['custom_fields'][$t_cfid][1] . ' AND ' . $t_filter['custom_fields'][$t_cfid][2]; break; } } else { array_push( $t_join_clauses, $t_cf_join_clause ); $t_filter_array = array(); foreach( $t_filter['custom_fields'][$t_cfid] as $t_filter_member ) { $t_filter_member = stripslashes( $t_filter_member ); if( filter_field_is_none( $t_filter_member ) ) { # coerce filter value if selecting META_FILTER_NONE so it will match empty fields $t_filter_member = ''; # but also add those _not_ present in the custom field string table array_push( $t_filter_array, "$t_bug_table.id NOT IN (SELECT bug_id FROM $t_custom_field_string_table WHERE field_id=$t_cfid)" ); } switch( $t_def['type'] ) { case CUSTOM_FIELD_TYPE_CHECKBOX: case CUSTOM_FIELD_TYPE_MULTILIST: $t_where_params[] = '%|' . $t_filter_member . '|%'; array_push( $t_filter_array, db_helper_like( "$t_table_name.value" ) ); break; case CUSTOM_FIELD_TYPE_TEXTAREA: $t_where_params[] = '%' . $t_filter_member . '%'; array_push( $t_filter_array, db_helper_like( "$t_table_name.text" ) ); break; default: $t_where_params[] = $t_filter_member; array_push( $t_filter_array, "$t_table_name.value = " . db_param() ); } } $t_custom_where_clause .= '(' . implode( ' OR ', $t_filter_array ); } if( !is_blank( $t_custom_where_clause ) ) { array_push( $t_where_clauses, $t_custom_where_clause . ')' ); } } } } # Text search if( !is_blank( $t_filter[FILTER_PROPERTY_SEARCH] ) ) { # break up search terms by spacing or quoting preg_match_all( "/-?([^'\"\s]+|\"[^\"]+\"|'[^']+')/", $t_filter[FILTER_PROPERTY_SEARCH], $t_matches, PREG_SET_ORDER ); # organize terms without quoting, paying attention to negation $t_search_terms = array(); foreach( $t_matches as $t_match ) { $t_search_terms[ trim( $t_match[1], "\'\"" ) ] = ( $t_match[0][0] == '-' ); } # build a big where-clause and param list for all search terms, including negations $t_first = true; $t_textsearch_where_clause = "( "; foreach( $t_search_terms as $t_search_term => $t_negate ) { if ( !$t_first ) { $t_textsearch_where_clause .= ' AND '; } if ( $t_negate ) { $t_textsearch_where_clause .= 'NOT '; } $c_search = '%' . $t_search_term . '%'; $t_textsearch_where_clause .= '( ' . db_helper_like( 'summary' ) . ' OR ' . db_helper_like( "$t_bug_text_table.description" ) . ' OR ' . db_helper_like( "$t_bug_text_table.steps_to_reproduce" ) . ' OR ' . db_helper_like( "$t_bug_text_table.additional_information" ) . ' OR ' . db_helper_like( "$t_bugnote_text_table.note" ); $t_where_params[] = $c_search; $t_where_params[] = $c_search; $t_where_params[] = $c_search; $t_where_params[] = $c_search; $t_where_params[] = $c_search; if( is_numeric( $t_search_term ) ) { $c_search_int = (int) $t_search_term; $t_textsearch_where_clause .= " OR $t_bug_table.id = " . db_param(); $t_textsearch_where_clause .= " OR $t_bugnote_table.id = " . db_param(); $t_where_params[] = $c_search_int; $t_where_params[] = $c_search_int; } $t_textsearch_where_clause .= ' )'; $t_first = false; } $t_textsearch_where_clause .= ' )'; # add text query elements to arrays if ( !$t_first ) { $t_from_clauses[] = "$t_bug_text_table"; $t_where_clauses[] = "$t_bug_table.bug_text_id = $t_bug_text_table.id"; $t_where_clauses[] = $t_textsearch_where_clause; $t_join_clauses[] = " LEFT JOIN $t_bugnote_table ON $t_bug_table.id = $t_bugnote_table.bug_id"; $t_join_clauses[] = " LEFT JOIN $t_bugnote_text_table ON $t_bugnote_table.bugnote_text_id = $t_bugnote_text_table.id"; } } # End text search $t_from_clauses[] = $t_project_table; $t_from_clauses[] = $t_bug_table; $t_query_clauses['select'] = $t_select_clauses; $t_query_clauses['from'] = $t_from_clauses; $t_query_clauses['join'] = $t_join_clauses; $t_query_clauses['where'] = $t_where_clauses; $t_query_clauses['where_values'] = $t_where_params; $t_query_clauses = filter_get_query_sort_data( $t_filter, $p_show_sticky, $t_query_clauses ); # assigning to $p_* for this function writes the values back in case the caller wants to know # Get the total number of bugs that meet the criteria. $p_bug_count = filter_get_bug_count( $t_query_clauses ); if( 0 == $p_bug_count ) { return array(); } $p_per_page = filter_per_page( $t_filter, $p_bug_count, $p_per_page ); $p_page_count = filter_page_count( $p_bug_count, $p_per_page ); $p_page_number = filter_valid_page_number( $p_page_number, $p_page_count ); $t_offset = filter_offset( $p_page_number, $p_per_page ); $t_query_clauses = filter_unique_query_clauses( $t_query_clauses ); $t_select_string = "SELECT DISTINCT " . implode( ', ', $t_query_clauses['select'] ); $t_from_string = " FROM " . implode( ', ', $t_query_clauses['from'] ); $t_order_string = " ORDER BY " . implode( ', ', $t_query_clauses['order'] ); $t_join_string = count( $t_query_clauses['join'] ) > 0 ? implode( ' ', $t_query_clauses['join'] ) : ''; $t_where_string = count( $t_query_clauses['where'] ) > 0 ? 'WHERE ' . implode( ' AND ', $t_query_clauses['where'] ) : ''; $t_result = db_query_bound( "$t_select_string $t_from_string $t_join_string $t_where_string $t_order_string", $t_query_clauses['where_values'], $p_per_page, $t_offset ); $t_row_count = db_num_rows( $t_result ); $t_id_array_lastmod = array(); for( $i = 0;$i < $t_row_count;$i++ ) { $t_row = db_fetch_array( $t_result ); $t_id_array_lastmod[] = (int) $t_row['id']; $t_rows[] = $t_row; } return filter_cache_result( $t_rows, $t_id_array_lastmod ); } /** * Cache the filter results with bugnote stats for later use * @param array $p_rows results of the filter query * @param array $p_id_array_lastmod array of bug ids * @return array */ function filter_cache_result( $p_rows, $p_id_array_lastmod ) { $t_bugnote_table = db_get_table( 'bugnote' ); $t_id_array_lastmod = array_unique( $p_id_array_lastmod ); $t_where_string = "WHERE $t_bugnote_table.bug_id in (" . implode( ", ", $t_id_array_lastmod ) . ')'; $t_query = "SELECT DISTINCT bug_id,MAX(last_modified) as last_modified, COUNT(last_modified) as count FROM $t_bugnote_table $t_where_string GROUP BY bug_id"; # perform query $t_result = db_query_bound( $t_query ); $t_row_count = db_num_rows( $t_result ); for( $i = 0;$i < $t_row_count;$i++ ) { $t_row = db_fetch_array( $t_result ); $t_stats[$t_row['bug_id']] = $t_row; } $t_rows = array(); foreach( $p_rows as $t_row ) { if( !isset( $t_stats[$t_row['id']] ) ) { $t_rows[] = bug_row_to_object( bug_cache_database_result( $t_row, false ) ); } else { $t_rows[] = bug_row_to_object( bug_cache_database_result( $t_row, $t_stats[ $t_row['id'] ] ) ); } } return $t_rows; } /** * Mainly based on filter_draw_selection_area2() but adds the support for the collapsible * filter display. * @param int $p_page_number * @param bool $p_for_screen * @see filter_draw_selection_area2 */ function filter_draw_selection_area( $p_page_number, $p_for_screen = true ) { collapse_open( 'filter' ); filter_draw_selection_area2( $p_page_number, $p_for_screen, true ); collapse_closed( 'filter' ); filter_draw_selection_area2( $p_page_number, $p_for_screen, false ); collapse_end( 'filter' ); } /** * Prints the filter selection area for both the bug list view screen and * the bug list print screen. This function was an attempt to make it easier to * add new filters and rearrange them on screen for both pages. * @param int $p_page_number * @param bool $p_for_screen * @param bool $p_expanded */ function filter_draw_selection_area2( $p_page_number, $p_for_screen = true, $p_expanded = true ) { $t_form_name_suffix = $p_expanded ? '_open' : '_closed'; $t_filter = current_user_get_bug_filter(); $t_filter = filter_ensure_valid_filter( $t_filter ); $t_project_id = helper_get_current_project(); $t_page_number = (int) $p_page_number; $t_view_type = $t_filter['_view_type']; $t_tdclass = 'small-caption'; $t_trclass = 'row-category2'; $t_action = 'view_all_set.php?f=3'; if( $p_for_screen == false ) { $t_tdclass = 'print'; $t_trclass = ''; $t_action = 'view_all_set.php'; } ?>
'; echo ''; } ?> 0 ) { $t_per_row = config_get( 'filter_custom_fields_per_row' ); $t_num_custom_rows = ceil( count( $t_accessible_custom_fields_ids ) / $t_per_row ); } } $t_filters_url = 'view_filters_page.php?for_screen=' . $p_for_screen; if( 'advanced' == $t_view_type ) { $t_filters_url = $t_filters_url . '&view_type=advanced'; } $t_filters_url = $t_filters_url . '&target_field='; $t_show_product_version = version_should_show_product_version( $t_project_id ); $t_show_build = $t_show_product_version && ( config_get( 'enable_product_build' ) == ON ); # overload handler_id setting if user isn't supposed to see them (ref #6189) if( !access_has_project_level( config_get( 'view_handler_threshold' ), $t_project_id ) ) { $t_filter[FILTER_PROPERTY_HANDLER_ID] = array( META_FILTER_ANY, ); } $t_dynamic_filter_expander_class = ( config_get( 'use_javascript' ) && config_get( 'use_dynamic_filters' ) ) ? ' class="dynamic-filter-expander"' : ''; ?> > 8 ) { echo ''; }?> 8 ) { echo ''; }?> > 8 ) { echo ''; }?> 8 ) { echo ''; }?> > 8 ) { echo ''; }?> 8 ) { echo ''; }?> > 8 ) { echo ''; }?> $t_filter_object ) { # be sure the colspan is an integer $t_colspan = (int) $t_filter_object->colspan; # prevent silliness. if( $t_colspan < 0 ) { $t_colspan = abs( $t_colspan ); } else if( $t_colspan > $t_filter_cols ) { $t_colspan = $t_filter_cols; } else if( $t_colspan == 0 ) { $t_colspan = 1; } # the row may already have elements in it. find out. $t_columns_available = $t_filter_cols - $t_column_count_by_row[$t_row]; if( $t_columns_available == 0 ) { $t_row++; } # see if there is room in the current row if( $t_columns_available >= $t_colspan ) { $t_assigned_row = $t_row; $t_column_count_by_row[$t_row] += $t_colspan; } else { $t_is_assigned = false; # find a row with space foreach( $t_column_count_by_row AS $t_row_num=>$t_col_count ) { if( $t_colspan <= ( $t_filter_cols - $t_col_count ) ) { $t_assigned_row = $t_row_num; $t_column_count_by_row[$t_row_num] += $t_colspan; $t_is_assigned = true; break; } } if( !$t_is_assigned ) { # no space was found in existing rows. Add a new row for it. $t_assigned_row = count( $t_plugin_filter_links ); $t_column_count_by_row[$t_assigned_row] = $t_colspan; } } $t_colspan_attr = ( $t_colspan > 1 ? 'colspan="' . $t_colspan . '" ' : '' ); $t_plugin_filter_links[$t_assigned_row][] = ''; $t_values = ''; $t_plugin_filter_fields[$t_assigned_row][] = $t_values; } $t_row_count = count( $t_plugin_filter_links ); for( $i=0; $i<$t_row_count; $i++ ) { if( $t_column_count_by_row[$i] < $t_filter_cols ) { $t_plugin_filter_links[$i][] = ''; $t_plugin_filter_fields[$i][] = ''; } $t_links_row = "\n\t\t" . join( "\n\t\t", $t_plugin_filter_links[$i] ); $t_values_row = "\n\t\t" . join( "\n\t\t", $t_plugin_filter_fields[$i] ); echo "\n\t" . '', $t_links_row, "\n\t"; echo "\n\t" . '', $t_values_row, "\n\t\n\t"; } if( ON == config_get( 'filter_by_custom_fields' ) ) { # -- Custom Field Searching -- if( count( $t_accessible_custom_fields_ids ) > 0 ) { $t_per_row = config_get( 'filter_custom_fields_per_row' ); $t_num_fields = count( $t_accessible_custom_fields_ids ); $t_row_idx = 0; $t_col_idx = 0; $t_fields = ''; $t_values = ''; for( $i = 0;$i < $t_num_fields;$i++ ) { if( $t_col_idx == 0 ) { $t_fields = ''; $t_values = ''; } if( isset( $t_accessible_custom_fields_names[$i] ) ) { $t_fields .= ' '; } $t_output = ''; $t_any_found = false; $t_values .= ''; $t_col_idx++; if( $t_col_idx == $t_per_row ) { if( $t_filter_cols > $t_per_row ) { $t_fields .= ' '; $t_values .= ' '; } $t_fields .= '' . "\n"; $t_values .= '' . "\n"; echo $t_fields; echo $t_values; $t_col_idx = 0; $t_row_idx++; } } if( $t_col_idx > 0 ) { if( $t_col_idx < $t_per_row ) { $t_fields .= ' '; $t_values .= ' '; } if( $t_filter_cols > $t_per_row ) { $t_fields .= ' '; $t_values .= ' '; } $t_fields .= '' . "\n"; $t_values .= '' . "\n"; echo $t_fields; echo $t_values; } } } ?> 6 ) { echo ''; } } else { if( $t_filter_cols > 3 ) { echo ''; } } ?>
> > > > > > >  
'; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_myself( $t_current ) ) { if( access_has_project_level( config_get( 'report_bug_threshold' ) ) ) { $t_this_name = '[' . lang_get( 'myself' ) . ']'; } else { $t_any_found = true; } } else if( filter_field_is_none( $t_current ) ) { $t_this_name = lang_get( 'none' ); } else { $t_this_name = user_get_name( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_name; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo string_display( $t_output ); } } ?>
'; $t_this_name = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_myself( $t_current ) ) { if( access_has_project_level( config_get( 'monitor_bug_threshold' ) ) ) { $t_this_name = '[' . lang_get( 'myself' ) . ']'; } else { $t_any_found = true; } } else { $t_this_name = user_get_name( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_name; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo string_display( $t_output ); } } ?>
'; $t_this_name = ''; if( filter_field_is_none( $t_current ) ) { $t_this_name = lang_get( 'none' ); } else if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_myself( $t_current ) ) { if( access_has_project_level( config_get( 'handle_bug_threshold' ) ) ) { $t_this_name = '[' . lang_get( 'myself' ) . ']'; } else { $t_any_found = true; } } else { $t_this_name = user_get_name( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_name; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo string_display( $t_output ); } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else { $t_this_string = string_display( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else { $t_this_string = get_enum_element( 'severity', $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else { $t_this_string = get_enum_element( 'resolution', $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else { $t_profile = profile_get_row_direct( $t_current ); $t_this_string = "${t_profile['platform']} ${t_profile['os']} ${t_profile['os_build']}"; } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
 
> > > > >     > >    
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else { $t_this_string = get_enum_element( 'status', $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
'; $t_this_string = ''; if( filter_field_is_none( $t_current ) ) { $t_none_found = true; } else { $t_this_string = get_enum_element( 'status', $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } $t_hide_status_post = ''; if( count( $t_filter[FILTER_PROPERTY_HIDE_STATUS] ) == 1 ) { $t_hide_status_post = ' (' . lang_get( 'and_above' ) . ')'; } if( true == $t_none_found ) { echo lang_get( 'none' ); } else { echo $t_output . $t_hide_status_post; } } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_none( $t_current ) ) { $t_this_string = lang_get( 'none' ); } else { $t_this_string = string_display( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_none( $t_current ) ) { $t_this_string = lang_get( 'none' ); } else { $t_this_string = string_display( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_none( $t_current ) ) { $t_this_string = lang_get( 'none' ); } else { $t_this_string = string_display( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
    '; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else { $t_this_string = get_enum_element( 'priority', $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
'; $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_none( $t_current ) ) { $t_this_string = lang_get( 'none' ); } else { $t_this_string = string_display( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } ?>
   
> > > > > >  
'; ?> '; ?> '; ?> '; echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; $t_chars = preg_split( '//', config_get( 'short_date_format' ), -1, PREG_SPLIT_NO_EMPTY ); $t_time = mktime( 0, 0, 0, $t_filter[FILTER_PROPERTY_START_MONTH], $t_filter[FILTER_PROPERTY_START_DAY], $t_filter[FILTER_PROPERTY_START_YEAR] ); foreach( $t_chars as $t_char ) { if( strcasecmp( $t_char, "M" ) == 0 ) { echo ' '; echo date( 'F', $t_time ); } if( strcasecmp( $t_char, "D" ) == 0 ) { echo ' '; echo date( 'd', $t_time ); } if( strcasecmp( $t_char, "Y" ) == 0 ) { echo ' '; echo date( 'Y', $t_time ); } } echo ' - '; $t_time = mktime( 0, 0, 0, $t_filter[FILTER_PROPERTY_END_MONTH], $t_filter[FILTER_PROPERTY_END_DAY], $t_filter[FILTER_PROPERTY_END_YEAR] ); foreach( $t_chars as $t_char ) { if( strcasecmp( $t_char, "M" ) == 0 ) { echo ' '; echo date( 'F', $t_time ); } if( strcasecmp( $t_char, "D" ) == 0 ) { echo ' '; echo date( 'd', $t_time ); } if( strcasecmp( $t_char, "Y" ) == 0 ) { echo ' '; echo date( 'Y', $t_time ); } } } else { echo lang_get( 'no' ); } ?> '; echo ''; $c_rel_type = $t_filter[FILTER_PROPERTY_RELATIONSHIP_TYPE]; $c_rel_bug = $t_filter[FILTER_PROPERTY_RELATIONSHIP_BUG]; if( -1 == $c_rel_type || 0 == $c_rel_bug ) { echo lang_get( 'any' ); } else { echo relationship_get_description_for_history( $c_rel_type ) . ' ' . $c_rel_bug; } ?>  
> > > >  
  '; ?>
' . string_display_line( $t_filter_object->title ) . ' '; if ( !isset( $t_filter[ $t_field_name ] ) ) { $t_values .= lang_get( 'any' ); } else { switch( $t_filter_object->type ) { case FILTER_TYPE_STRING: case FILTER_TYPE_INT: if ( filter_field_is_any( $t_filter[ $t_field_name ] ) ) { $t_values .= lang_get( 'any' ); } else { $t_values .= string_display( $t_filter[ $t_field_name ] ); } $t_values .= ''; break; case FILTER_TYPE_BOOLEAN: $t_values .= string_display( $t_filter_object->display( (bool)$t_filter[ $t_field_name ] ) ); $t_values .= ''; break; case FILTER_TYPE_MULTI_STRING: case FILTER_TYPE_MULTI_INT: $t_first = true; $t_output = ''; if ( !is_array( $t_filter[ $t_field_name ] ) ) { $t_filter[ $t_field_name ] = array( $t_filter[ $t_field_name ] ); } foreach( $t_filter[ $t_field_name ] as $t_current ) { if ( filter_field_is_any( $t_current ) ) { $t_output .= lang_get( 'any' ); } else { $t_output .= ( $t_first ? '' : '
' ) . string_display( $t_filter_object->display( $t_current ) ); $t_first = false; } $t_values .= ''; } $t_values .= $t_output; break; } } $t_values .= '
  
'; $t_fields .= ''; $t_fields .= string_display( lang_get_defaulted( $t_accessible_custom_fields_names[$i] ) ); $t_fields .= ' '; if( !isset( $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]] ) ) { $t_values .= lang_get( 'any' ); } else { if( $t_accessible_custom_fields_types[$i] == CUSTOM_FIELD_TYPE_DATE ) { $t_short_date_format = config_get( 'short_date_format' ); if( !isset( $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][1] ) ) { $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][1] = 0; } $t_start = date( $t_short_date_format, $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][1] ); if( !isset( $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][2] ) ) { $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][2] = 0; } $t_end = date( $t_short_date_format, $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][2] ); switch( $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][0] ) { case CUSTOM_FIELD_DATE_ANY: $t_values .= lang_get( 'any' ); break; case CUSTOM_FIELD_DATE_NONE: $t_values .= lang_get( 'none' ); break; case CUSTOM_FIELD_DATE_BETWEEN: $t_values .= lang_get( 'between_date' ) . '
'; $t_values .= $t_start . '
' . $t_end; break; case CUSTOM_FIELD_DATE_ONORBEFORE: $t_values .= lang_get( 'on_or_before_date' ) . '
'; $t_values .= $t_end; break; case CUSTOM_FIELD_DATE_BEFORE: $t_values .= lang_get( 'before_date' ) . '
'; $t_values .= $t_end; break; case CUSTOM_FIELD_DATE_ON: $t_values .= lang_get( 'on_date' ) . '
'; $t_values .= $t_start; break; case CUSTOM_FIELD_DATE_AFTER: $t_values .= lang_get( 'after_date' ) . '
'; $t_values .= $t_start; break; case CUSTOM_FIELD_DATE_ONORAFTER: $t_values .= lang_get( 'on_or_after_date' ) . '
'; $t_values .= $t_start; break; } } else { $t_first_flag = true; foreach( $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]] as $t_current ) { $t_current = stripslashes( $t_current ); $t_this_string = ''; if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_none( $t_current ) ) { $t_this_string = lang_get( 'none' ); } else { $t_this_string = string_display( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_string; $t_values .= ''; } } if( true == $t_any_found ) { $t_values .= lang_get( 'any' ); } else { $t_values .= $t_output; } } $t_values .= '
  
    
> '; $t_this_name = ''; if( filter_field_is_none( $t_current ) ) { $t_this_name = lang_get( 'none' ); } else if( filter_field_is_any( $t_current ) ) { $t_any_found = true; } else if( filter_field_is_myself( $t_current ) ) { if( access_has_project_level( config_get( 'handle_bug_threshold' ) ) ) { $t_this_name = '[' . lang_get( 'myself' ) . ']'; } else { $t_any_found = true; } } else { $t_this_name = user_get_name( $t_current ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . $t_this_name; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo string_display( $t_output ); } } ?>
> '; echo ''; } } ?> > '; $t_this_name = ''; if( META_FILTER_CURRENT == $t_current ) { $t_this_name = lang_get( 'current' ); } else { $t_this_name = project_get_name( $t_current, false ); } if( $t_first_flag != true ) { $t_output = $t_output . '
'; } else { $t_first_flag = false; } $t_output = $t_output . string_display_line( $t_this_name ); } echo $t_output; } ?>
  
'; echo ''; echo '
'; ?>
0 ) { ?>

name="[]"> '' ) && ( ON == config_get( 'show_realname' ) ) ) { $t_display_name = string_attribute( $t_realname ); } echo ''; } else { ?> [' . lang_get( 'myself' ) . ']'; } print_reporter_option_list( $t_filter[FILTER_PROPERTY_REPORTER_ID] ); }?> name="[]"> [' . lang_get( 'myself' ) . ']'; } $t_threshold = config_get( 'show_monitor_list_threshold' ); $t_has_project_level = access_has_project_level( $t_threshold ); if( $t_has_project_level ) { print_reporter_option_list( $t_filter[FILTER_PROPERTY_MONITOR_USER_ID] ); } ?> name="[]"> [' . lang_get( 'myself' ) . ']'; } print_assign_to_option_list( $t_filter[FILTER_PROPERTY_HANDLER_ID] ); }?> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> name="[]"> />
'; print_month_option_list( $t_filter[FILTER_PROPERTY_START_MONTH] ); print "\n"; } if( strcasecmp( $t_char, "D" ) == 0 ) { echo '\n"; } if( strcasecmp( $t_char, "Y" ) == 0 ) { echo '\n"; } } ?>
'; print_month_option_list( $t_filter[FILTER_PROPERTY_END_MONTH] ); print "\n"; } if( strcasecmp( $t_char, "D" ) == 0 ) { echo '\n"; } if( strcasecmp( $t_char, "Y" ) == 0 ) { echo '\n"; } } ?>
'; } /** * print tag fields */ function print_filter_tag_string() { if ( !access_has_global_level( config_get( 'tag_view_threshold' ) ) ) { return; } global $t_filter; $t_tag_string = $t_filter[FILTER_PROPERTY_TAG_STRING]; if( $t_filter[FILTER_PROPERTY_TAG_SELECT] != 0 && tag_exists( $t_filter[FILTER_PROPERTY_TAG_SELECT] ) ) { $t_tag_string .= ( is_blank( $t_tag_string ) ? '' : config_get( 'tag_separator' ) ); $t_tag_string .= tag_get_field( $t_filter[FILTER_PROPERTY_TAG_SELECT], 'name' ); } ?> name="[]"> [' . lang_get( 'myself' ) . ']'; } print_assign_to_option_list( $t_filter[FILTER_PROPERTY_NOTE_USER_ID] ); } ?> size; switch( $p_filter_object->type ) { case FILTER_TYPE_STRING: echo ' 0 ? " size=\"$t_size\"" : '' ), ' value="', string_attribute( $t_filter[ $p_field_name ] ), '"/>'; break; case FILTER_TYPE_INT: echo ' 0 ? " size=\"$t_size\"" : '' ), ' value="', (int) $t_filter[ $p_field_name ], '"/>'; break; case FILTER_TYPE_BOOLEAN: echo ' 0 ? " size=\"$t_size\"" : '' ), check_checked( (bool) $t_filter[ $p_field_name ] ) , '"/>'; break; case FILTER_TYPE_MULTI_STRING: echo ' 0 ? " size=\"$t_size\"" : '' ), ' name="', string_attribute( $p_field_name ), '[]">', ''; foreach( $p_filter_object->options() as $t_option_value => $t_option_name ) { echo ''; } echo ''; break; case FILTER_TYPE_MULTI_INT: echo ' 0 ? " size=\"$t_size\"" : '' ), ' name="', string_attribute( $p_field_name ), '[]">', ''; foreach( $p_filter_object->options() as $t_option_value => $t_option_name ) { echo ''; } echo ''; break; } } /** * print custom fields * @param int $p_field_id */ function print_filter_custom_field( $p_field_id ) { global $t_filter, $t_accessible_custom_fields_names, $t_accessible_custom_fields_types, $t_accessible_custom_fields_values, $t_accessible_custom_fields_ids, $t_select_modifier; $j = array_search( $p_field_id, $t_accessible_custom_fields_ids ); if( $j === null || $j === false ) { # Note: Prior to PHP 4.2.0, array_search() returns NULL on failure instead of FALSE. ?> unknown custom filter (custom ) '; } else { echo ''; echo ''; # don't show META_FILTER_NONE for enumerated types as it's not possible for them to be blank if( !in_array( $t_accessible_custom_fields_types[$j], array( CUSTOM_FIELD_TYPE_ENUM, CUSTOM_FIELD_TYPE_LIST, CUSTOM_FIELD_TYPE_MULTILIST ) ) ) { echo ''; } if( is_array( $t_accessible_custom_fields_values[$j] ) ) { $t_max_length = config_get( 'max_dropdown_length' ); foreach( $t_accessible_custom_fields_values[$j] as $t_item ) { if(( utf8_strtolower( $t_item ) !== META_FILTER_ANY ) && ( utf8_strtolower( $t_item ) !== META_FILTER_NONE ) ) { echo '' . "\n"; } } } echo ''; } } } /** * print sort fields */ function print_filter_show_sort() { global $t_filter; # get all of the displayed fields for sort, then drop ones that # are not appropriate and translate the rest $t_fields = helper_get_columns_to_view(); $t_n_fields = count( $t_fields ); $t_shown_fields[''] = ''; for( $i = 0;$i < $t_n_fields;$i++ ) { if( !in_array( $t_fields[$i], array( 'selection', 'edit', 'bugnotes_count', 'attachment' ) ) ) { if( strpos( $t_fields[$i], 'custom_' ) === 0 ) { $t_field_name = string_display( lang_get_defaulted( utf8_substr( $t_fields[$i], utf8_strlen( 'custom_' ) ) ) ); } else { $t_field_name = string_get_field_name( $t_fields[$i] ); } $t_shown_fields[$t_fields[$i]] = $t_field_name; } } $t_shown_dirs[''] = ''; $t_shown_dirs['ASC'] = lang_get( 'bugnote_order_asc' ); $t_shown_dirs['DESC'] = lang_get( 'bugnote_order_desc' ); # get default values from filter structure $t_sort_fields = explode( ',', $t_filter[FILTER_PROPERTY_SORT_FIELD_NAME] ); $t_dir_fields = explode( ',', $t_filter[FILTER_PROPERTY_SORT_DIRECTION] ); if( !isset( $t_sort_fields[1] ) ) { $t_sort_fields[1] = ''; $t_dir_fields[1] = ''; } # if there are fields to display, show the dropdowns if( count( $t_fields ) > 0 ) { # display a primary and secondary sort fields echo ''; echo ''; echo ', '; # for secondary sort echo ''; echo ''; } else { echo lang_get_defaulted( 'last_updated' ) . lang_get( 'bugnote_order_desc' ); echo ''; echo ''; } } /** * print custom field date fields * @param int $p_field_num * @param int $p_field_id */ function print_filter_custom_field_date( $p_field_num, $p_field_id ) { global $t_filter, $t_accessible_custom_fields_names, $t_accessible_custom_fields_types, $t_accessible_custom_fields_values, $t_accessible_custom_fields_ids, $t_select_modifier; $t_js_toggle_func = 'toggle_custom_date_field_' . $p_field_id . '_controls'; # Resort the values so there ordered numerically, they are sorted as strings otherwise which # may be wrong for dates before early 2001. if( is_array( $t_accessible_custom_fields_values[$p_field_num] ) ) { array_multisort( $t_accessible_custom_fields_values[$p_field_num], SORT_NUMERIC, SORT_ASC ); } if( isset( $t_accessible_custom_fields_values[$p_field_num][0] ) ) { $t_sel_start_year = date( 'Y', $t_accessible_custom_fields_values[$p_field_num][0] ); } $t_count = count( $t_accessible_custom_fields_values[$p_field_num] ); if( isset( $t_accessible_custom_fields_values[$p_field_num][$t_count - 1] ) ) { $t_sel_end_year = date( 'Y', $t_accessible_custom_fields_values[$p_field_num][$t_count - 1] ); } $t_start = date( 'U' ); # Default to today in filters.. $t_end = $t_start; if( isset( $t_filter['custom_fields'][$p_field_id][1] ) ) { $t_start_time = $t_filter['custom_fields'][$p_field_id][1]; } else { $t_start_time = 0; } if( isset( $t_filter['custom_fields'][$p_field_id][2] ) ) { $t_end_time = $t_filter['custom_fields'][$p_field_id][2]; } else { $t_end_time = 0; } $t_start_disable = true; $t_end_disable = true; // if $t_filter['custom_fields'][$p_field_id][0] is not set (ie no filter), we will drop through the // following switch and use the default values above, so no need to check if stuff is set or not. switch( $t_filter['custom_fields'][$p_field_id][0] ) { case CUSTOM_FIELD_DATE_ANY: case CUSTOM_FIELD_DATE_NONE: break; case CUSTOM_FIELD_DATE_BETWEEN: $t_start_disable = false; $t_end_disable = false; $t_start = $t_start_time; $t_end = $t_end_time; break; case CUSTOM_FIELD_DATE_ONORBEFORE: $t_start_disable = false; $t_start = $t_end_time; break; case CUSTOM_FIELD_DATE_BEFORE: $t_start_disable = false; $t_start = $t_end_time; break; case CUSTOM_FIELD_DATE_ON: $t_start_disable = false; $t_start = $t_start_time; break; case CUSTOM_FIELD_DATE_AFTER: $t_start_disable = false; $t_start = $t_start_time; break; case CUSTOM_FIELD_DATE_ONORAFTER: $t_start_disable = false; $t_start = $t_start_time; break; } echo "\n\n\n\n
\n"; echo "' . "\n"; echo "
"; print_date_selection_set( 'custom_field_' . $p_field_id . '_start', config_get( 'short_date_format' ), $t_start, $t_start_disable, false, $t_sel_start_year, $t_sel_end_year ); print "
"; print_date_selection_set( 'custom_field_' . $p_field_id . '_end', config_get( 'short_date_format' ), $t_end, $t_end_disable, false, $t_sel_start_year, $t_sel_end_year ); print "
"; } /** * print project field */ function print_filter_project_id() { global $t_select_modifier, $t_filter, $f_view_type; ?> name="[]"> '; } else { $t_first_flag = false; } $t_output .= $t_this_string; } if( true == $t_any_found ) { echo lang_get( 'any' ); } else { echo $t_output; } } } # ========================================================================== # CACHING # ========================================================================== /** * @internal SECURITY NOTE: cache globals are initialized here to prevent them * being spoofed if register_globals is turned on. * We cache filter requests to reduce the number of SQL queries * @global mixed $g_cache_filter * @global mixed $g_cache_filter_db_filters */ $g_cache_filter = array(); $g_cache_filter_db_filters = array(); /** * Cache a filter row if necessary and return the cached copy * If the second parameter is true (default), trigger an error * if the filter can't be found. If the second parameter is * false, return false if the filter can't be found. * @param int $p_filter_id * @param bool $p_trigger_errors * @return mixed */ function filter_cache_row( $p_filter_id, $p_trigger_errors = true ) { global $g_cache_filter; $c_filter_id = db_prepare_int( $p_filter_id ); $t_filters_table = db_get_table( 'filters' ); if( isset( $g_cache_filter[$c_filter_id] ) ) { return $g_cache_filter[$c_filter_id]; } $query = 'SELECT * FROM ' . $t_filters_table . ' WHERE id=' . db_param(); $result = db_query_bound( $query, Array( $c_filter_id ) ); if( 0 == db_num_rows( $result ) ) { if( $p_trigger_errors ) { error_parameters( $p_filter_id ); trigger_error( ERROR_FILTER_NOT_FOUND, ERROR ); } else { return false; } } $row = db_fetch_array( $result ); $g_cache_filter[$c_filter_id] = $row; return $row; } /** * Clear the filter cache (or just the given id if specified) * @param int $p_filter_id * @return bool */ function filter_clear_cache( $p_filter_id = null ) { global $g_cache_filter; if( null === $p_filter_id ) { $g_cache_filter = array(); } else { $c_filter_id = db_prepare_int( $p_filter_id ); unset( $g_cache_filter[$c_filter_id] ); } return true; } # ========================================================================== # FILTER DB FUNCTIONS # ========================================================================== /** * Add a filter to the database for the current user * @param int $p_project_id * @param bool $p_is_public * @param string $p_name * @param string $p_filter_string * @return int */ function filter_db_set_for_current_user( $p_project_id, $p_is_public, $p_name, $p_filter_string ) { $t_user_id = auth_get_current_user_id(); $c_project_id = db_prepare_int( $p_project_id ); $c_is_public = db_prepare_bool( $p_is_public, false ); $t_filters_table = db_get_table( 'filters' ); # check that the user can save non current filters (if required) if(( ALL_PROJECTS <= $c_project_id ) && ( !is_blank( $p_name ) ) && ( !access_has_project_level( config_get( 'stored_query_create_threshold' ) ) ) ) { return -1; } # ensure that we're not making this filter public if we're not allowed if( !access_has_project_level( config_get( 'stored_query_create_shared_threshold' ) ) ) { $c_is_public = db_prepare_bool( false ); } # Do I need to update or insert this value? $query = "SELECT id FROM $t_filters_table WHERE user_id=" . db_param() . " AND project_id=" . db_param() . " AND name=" . db_param(); $result = db_query_bound( $query, Array( $t_user_id, $c_project_id, $p_name ) ); if( db_num_rows( $result ) > 0 ) { $row = db_fetch_array( $result ); $query = "UPDATE $t_filters_table SET is_public=" . db_param() . ", filter_string=" . db_param() . " WHERE id=" . db_param(); db_query_bound( $query, Array( $c_is_public, $p_filter_string, $row['id'] ) ); return $row['id']; } else { $query = "INSERT INTO $t_filters_table ( user_id, project_id, is_public, name, filter_string ) VALUES ( " . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ' )'; db_query_bound( $query, Array( $t_user_id, $c_project_id, $c_is_public, $p_name, $p_filter_string ) ); # Recall the query, we want the filter ID $query = "SELECT id FROM $t_filters_table WHERE user_id=" . db_param() . " AND project_id=" . db_param() . " AND name=" . db_param(); $result = db_query_bound( $query, Array( $t_user_id, $c_project_id, $p_name ) ); if( db_num_rows( $result ) > 0 ) { $row = db_fetch_array( $result ); return $row['id']; } return -1; } } /** * This function returns the filter string that is * tied to the unique id parameter. If the user doesn't * have permission to see this filter, the function * returns null * @param int $p_filter_id * @param int $p_user_id * @return mixed */ function filter_db_get_filter( $p_filter_id, $p_user_id = null ) { global $g_cache_filter_db_filters; $t_filters_table = db_get_table( 'filters' ); $c_filter_id = db_prepare_int( $p_filter_id ); if( isset( $g_cache_filter_db_filters[$p_filter_id] ) ) { if( $g_cache_filter_db_filters[$p_filter_id] === false ) { return null; } return $g_cache_filter_db_filters[$p_filter_id]; } if( null === $p_user_id ) { $t_user_id = auth_get_current_user_id(); } else { $t_user_id = $p_user_id; } $query = 'SELECT * FROM ' . $t_filters_table . ' WHERE id=' . db_param(); $result = db_query_bound( $query, Array( $c_filter_id ) ); if( db_num_rows( $result ) > 0 ) { $row = db_fetch_array( $result ); if( $row['user_id'] != $t_user_id ) { if( $row['is_public'] != true ) { return null; } } # check that the user has access to non current filters if(( ALL_PROJECTS <= $row['project_id'] ) && ( !is_blank( $row['name'] ) ) && ( !access_has_project_level( config_get( 'stored_query_use_threshold', $row['project_id'], $t_user_id ) ) ) ) { return null; } $g_cache_filter_db_filters[$p_filter_id] = $row['filter_string']; return $row['filter_string']; } else { $g_cache_filter_db_filters[$p_filter_id] = false; return false; } } /** * @param int $p_project_id * @param int $p_user_id * @return int */ function filter_db_get_project_current( $p_project_id, $p_user_id = null ) { $t_filters_table = db_get_table( 'filters' ); $c_project_id = db_prepare_int( $p_project_id ); $c_project_id = $c_project_id * -1; if( null === $p_user_id ) { $c_user_id = auth_get_current_user_id(); } else { $c_user_id = db_prepare_int( $p_user_id ); } # we store current filters for each project with a special project index $query = "SELECT * FROM $t_filters_table WHERE user_id=" . db_param() . " AND project_id=" . db_param() . " AND name=" . db_param(); $result = db_query_bound( $query, Array( $c_user_id, $c_project_id, '' ) ); if( db_num_rows( $result ) > 0 ) { $row = db_fetch_array( $result ); return $row['id']; } return null; } /** * Query for the filter name using the filter id * @param int $p_filter_id * @return string */ function filter_db_get_name( $p_filter_id ) { $t_filters_table = db_get_table( 'filters' ); $c_filter_id = db_prepare_int( $p_filter_id ); $query = 'SELECT * FROM ' . $t_filters_table . ' WHERE id=' . db_param(); $result = db_query_bound( $query, Array( $c_filter_id ) ); if( db_num_rows( $result ) > 0 ) { $row = db_fetch_array( $result ); if( $row['user_id'] != auth_get_current_user_id() ) { if( $row['is_public'] != true ) { return null; } } return $row['name']; } return null; } /** * Check if the current user has permissions to delete the stored query * @param $p_filter_id * @return bool */ function filter_db_can_delete_filter( $p_filter_id ) { $t_filters_table = db_get_table( 'filters' ); $c_filter_id = db_prepare_int( $p_filter_id ); $t_user_id = auth_get_current_user_id(); # Administrators can delete any filter if( user_is_administrator( $t_user_id ) ) { return true; } $query = "SELECT id FROM $t_filters_table WHERE id=" . db_param() . " AND user_id=" . db_param() . " AND project_id!=" . db_param(); $result = db_query_bound( $query, Array( $c_filter_id, $t_user_id, -1 ) ); if( db_num_rows( $result ) > 0 ) { return true; } return false; } /** * Delete the filter specified by $p_filter_id * @param $p_filter_id * @return bool */ function filter_db_delete_filter( $p_filter_id ) { $t_filters_table = db_get_table( 'filters' ); $c_filter_id = db_prepare_int( $p_filter_id ); $t_user_id = auth_get_current_user_id(); if( !filter_db_can_delete_filter( $c_filter_id ) ) { return false; } $query = 'DELETE FROM ' . $t_filters_table . ' WHERE id=' . db_param(); $result = db_query_bound( $query, Array( $c_filter_id ) ); if( db_affected_rows( $result ) > 0 ) { return true; } return false; } /** * Delete all the unnamed filters */ function filter_db_delete_current_filters() { $t_filters_table = db_get_table( 'filters' ); $t_all_id = ALL_PROJECTS; $query = "DELETE FROM $t_filters_table WHERE project_id<=" . db_param() . " AND name=" . db_param(); $result = db_query_bound( $query, Array( $t_all_id, '' ) ); } /** * @param int $p_project_id * @param int $p_user_id * @return mixed */ function filter_db_get_available_queries( $p_project_id = null, $p_user_id = null ) { $t_filters_table = db_get_table( 'filters' ); $t_overall_query_arr = array(); if( null === $p_project_id ) { $t_project_id = helper_get_current_project(); } else { $t_project_id = db_prepare_int( $p_project_id ); } if( null === $p_user_id ) { $t_user_id = auth_get_current_user_id(); } else { $t_user_id = db_prepare_int( $p_user_id ); } # If the user doesn't have access rights to stored queries, just return if( !access_has_project_level( config_get( 'stored_query_use_threshold' ) ) ) { return $t_overall_query_arr; } # Get the list of available queries. By sorting such that public queries are # first, we can override any query that has the same name as a private query # with that private one $query = "SELECT * FROM $t_filters_table WHERE (project_id=" . db_param() . " OR project_id=0) AND name!='' ORDER BY is_public DESC, name ASC"; $result = db_query_bound( $query, Array( $t_project_id ) ); $query_count = db_num_rows( $result ); for( $i = 0;$i < $query_count;$i++ ) { $row = db_fetch_array( $result ); if(( $row['user_id'] == $t_user_id ) || db_prepare_bool( $row['is_public'] ) ) { $t_overall_query_arr[$row['id']] = $row['name']; } } $t_overall_query_arr = array_unique( $t_overall_query_arr ); asort( $t_overall_query_arr ); return $t_overall_query_arr; } /** * @param str $p_name * @return bool true when under max_length (64) and false when over */ function filter_name_valid_length( $p_name ) { if( utf8_strlen( $p_name ) > 64 ) { return false; } else { return true; } }