View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0013180 | mantisbt | custom fields | public | 2011-07-26 09:35 | 2020-08-25 04:48 |
Reporter | rombert | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | confirmed | Resolution | open | ||
Summary | 0013180: Url template custom field | ||||
Description | We should provide a custom field of type url template. It would take a parameter of type template with a placeholder for substitution, e.g. http://www.example.com/view/%s?page=put This can be useful for integration with other systems, e.g Github's pull requests in our case. When rendered the field would be clickable and navigate to the linked page, with the substitution applied. | ||||
Tags | No tags attached. | ||||
Attached Files | 0001-Added-custom-field-Template.patch (13,128 bytes)
From c4507fdbe00b0a7a496fa12d21ca3708a8a865e2 Mon Sep 17 00:00:00 2001 From: Vincent Sels <vincent_sels@hotmail.com> Date: Sun, 5 Feb 2012 18:52:19 +0100 Subject: [PATCH] Added custom field 'Template' When choosing custom field type 'Template', you can define a template value with a placeholder ({0}) in the 'Default value' field. Upon entering a value for this custom field, it will be inserted in the template's placeholder. Links will be interpreted. --- config_defaults_inc.php | 2 +- core/cfdefs/cfdef_standard.php | 44 ++++++++++++++++++++++++++++++++++++++++ core/constant_inc.php | 1 + core/custom_field_api.php | 32 +++++++++++++--------------- core/email_api.php | 2 +- core/gpc_api.php | 1 + lang/strings_dutch.txt | 2 +- lang/strings_english.txt | 2 +- 8 files changed, 65 insertions(+), 21 deletions(-) diff --git a/config_defaults_inc.php b/config_defaults_inc.php index 7087dab..cd59cb1 100644 --- a/config_defaults_inc.php +++ b/config_defaults_inc.php @@ -3019,7 +3019,7 @@ * * @global string $g_custom_field_type_enum_string */ - $g_custom_field_type_enum_string = '0:string,1:numeric,2:float,3:enum,4:email,5:checkbox,6:list,7:multiselection list,8:date,9:radio'; + $g_custom_field_type_enum_string = '0:string,1:numeric,2:float,3:enum,4:email,5:checkbox,6:list,7:multiselection list,8:date,9:radio,10:template'; /********************************* * MantisBT Javascript Variables * diff --git a/core/cfdefs/cfdef_standard.php b/core/cfdefs/cfdef_standard.php index f358d3b..c1ea092 100644 --- a/core/cfdefs/cfdef_standard.php +++ b/core/cfdefs/cfdef_standard.php @@ -158,6 +158,20 @@ $g_custom_field_type_definition[ CUSTOM_FIELD_TYPE_DATE ] = array ( '#function_string_value_for_email' => 'cfdef_prepare_date_value_for_email', ); +$g_custom_field_type_definition[ CUSTOM_FIELD_TYPE_TEMPLATE ] = array ( + '#display_possible_values' => FALSE, + '#display_valid_regexp' => TRUE, + '#display_length_min' => TRUE, + '#display_length_max' => TRUE, + '#display_default_value' => TRUE, + '#function_return_distinct_values' => null, + '#function_value_to_database' => null, + '#function_database_to_value' => null, + '#function_print_input' => 'cfdef_input_textbox', + '#function_string_value' => 'cfdef_prepare_template_value', + '#function_string_value_for_email' => 'cfdef_prepare_template_value_for_email', +); + function cfdef_prepare_list_database_to_value($p_value) { return rtrim( ltrim( $p_value, '|' ), '|' ); } @@ -224,6 +238,36 @@ function cfdef_prepare_date_value($p_value) { } } +/** + * Replaces the wildcard '{0}' from the field's 'default value' with the specified $p_value. + * Also converts the resulting string to a link if applicable. + * @param $p_value The value to be inserted in the template + * @return string replaces the wildcard '{0}' from the 'default value' with the specified $p_value + */ +function cfdef_prepare_template_value($p_value, $p_field_def) { + $t_template = $p_field_def['default_value']; + + if ( empty( $p_value ) ) { + return ''; + } + + return string_display_line_links(str_replace('{0}', $p_value, $t_template)); +} + +/** + * Replaces the wildcard '{0}' from the field's 'default value' with the specified $p_value + * @param $p_value The value to be inserted in the template + * @return string replaces the wildcard '{0}' from the 'default value' with the specified $p_value + */ +function cfdef_prepare_template_value_for_email($p_value, $p_field_def) { + $t_template = $p_field_def['default_value']; + + if ( empty( $p_value ) ) { + return ''; + } + + return str_replace('{0}', $p_value, $t_template); +} #print_custom_field_input diff --git a/core/constant_inc.php b/core/constant_inc.php index a10a54b..149ec5e 100644 --- a/core/constant_inc.php +++ b/core/constant_inc.php @@ -416,6 +416,7 @@ define( 'CUSTOM_FIELD_TYPE_LIST', 6 ); define( 'CUSTOM_FIELD_TYPE_MULTILIST', 7 ); define( 'CUSTOM_FIELD_TYPE_DATE', 8 ); define( 'CUSTOM_FIELD_TYPE_RADIO', 9 ); +define( 'CUSTOM_FIELD_TYPE_TEMPLATE', 10 ); # Meta filter values define( 'META_FILTER_MYSELF', -1 ); diff --git a/core/custom_field_api.php b/core/custom_field_api.php index a6faa8a..4e6d8c4 100644 --- a/core/custom_field_api.php +++ b/core/custom_field_api.php @@ -53,6 +53,7 @@ $g_custom_field_types[CUSTOM_FIELD_TYPE_CHECKBOX] = 'standard'; $g_custom_field_types[CUSTOM_FIELD_TYPE_LIST] = 'standard'; $g_custom_field_types[CUSTOM_FIELD_TYPE_MULTILIST] = 'standard'; $g_custom_field_types[CUSTOM_FIELD_TYPE_DATE] = 'standard'; +$g_custom_field_types[CUSTOM_FIELD_TYPE_TEMPLATE] = 'standard'; foreach( $g_custom_field_types as $type ) { require_once( 'cfdefs' . DIRECTORY_SEPARATOR . 'cfdef_' . $type . '.php' ); @@ -380,9 +381,9 @@ function custom_field_has_write_access( $p_field_id, $p_bug_id, $p_user_id = nul } /** - * create a new custom field with the name $p_name - * the definition are the default values and can be changes later - * return the ID of the new definition + * create a new custom field with the name $p_name. + * the definition are the default values and can be changed later. + * return the ID of the new definition. * @param string $p_name custom field name * @return int custom field id * @access public @@ -413,7 +414,7 @@ function custom_field_create( $p_name ) { } /** - * Update the field definition + * Update the field definition. * return true on success, false on failure * @param int $p_field_id custom field id * @param array custom field definition @@ -984,9 +985,6 @@ function custom_field_get_value( $p_field_id, $p_bug_id ) { $row = custom_field_cache_row( $p_field_id ); - $t_access_level_r = $row['access_level_r']; - $t_default_value = $row['default_value']; - if( !custom_field_has_read_access( $p_field_id, $p_bug_id, auth_get_current_user_id() ) ) { return false; } @@ -1148,6 +1146,7 @@ function custom_field_validate( $p_field_id, $p_value ) { $t_length = utf8_strlen( $p_value ); switch ($t_type) { case CUSTOM_FIELD_TYPE_STRING: + case CUSTOM_FIELD_TYPE_TEMPLATE: # Regular expression string validation if( !is_blank( $t_valid_regexp ) && !is_blank( $p_value ) ) { $t_valid &= preg_match( "/$t_valid_regexp/", $p_value ); @@ -1243,7 +1242,6 @@ function custom_field_prepare_possible_values( $p_possible_values ) { function custom_field_distinct_values( $p_field_def, $p_project_id = ALL_PROJECTS ) { global $g_custom_field_type_definition; $c_field_id = $p_field_def['id']; - $c_project_id = db_prepare_int( $p_project_id ); $t_custom_field_string_table = db_get_table( 'mantis_custom_field_string_table' ); $t_mantis_bug_table = db_get_table( 'mantis_bug_table' ); $t_return_arr = array(); @@ -1414,10 +1412,10 @@ function custom_field_set_sequence( $p_field_id, $p_project_id, $p_sequence ) { /** * Print an input field - * $p_field_def contains the definition of the custom field (including it's field id + * $p_field_def contains the definition of the custom field (including its field id) * $p_bug_id contains the bug where this field belongs to. If it's left - * away, it'll default to 0 and thus belongs to a new (i.e. non-existant) bug - * NOTE: This probably belongs in the print_api.php + * away, it'll default to 0 and thus belong to a new (i.e. non-existant) bug + * @todo This probably belongs in the print_api.php * @param array $p_field_def custom field definition * @param int $p_bug_id bug id * @access public @@ -1461,14 +1459,14 @@ function string_custom_field_value( $p_def, $p_field_id, $p_bug_id ) { } global $g_custom_field_type_definition; if( isset( $g_custom_field_type_definition[$p_def['type']]['#function_string_value'] ) ) { - return call_user_func( $g_custom_field_type_definition[$p_def['type']]['#function_string_value'], $t_custom_field_value ); + return call_user_func( $g_custom_field_type_definition[$p_def['type']]['#function_string_value'], $t_custom_field_value , $p_def ); } return string_display_links( $t_custom_field_value ); } /** * Print a custom field value for display - * NOTE: This probably belongs in the print_api.php + * @todo This probably belongs in the print_api.php * @param array $p_def contains the definition of the custom field * @param int $p_field_id contains the id of the field * @param int $p_bug_id contains the bug id to display the custom field value for @@ -1481,16 +1479,16 @@ function print_custom_field_value( $p_def, $p_field_id, $p_bug_id ) { /** * Prepare a string containing a custom field value for email - * NOTE: This probably belongs in the string_api.php + * @todo This probably belongs in the string_api.php * @param string $p_value value of custom field * @param int $p_type type of custom field * @return string value ready for sending via email * @access public */ -function string_custom_field_value_for_email( $p_value, $p_type ) { +function string_custom_field_value_for_email( $p_value, $p_def ) { global $g_custom_field_type_definition; - if( isset( $g_custom_field_type_definition[$p_type]['#function_string_value_for_email'] ) ) { - return call_user_func( $g_custom_field_type_definition[$p_type]['#function_string_value_for_email'], $p_value ); + if( isset( $g_custom_field_type_definition[$p_def['type']]['#function_string_value_for_email'] ) ) { + return call_user_func( $g_custom_field_type_definition[$p_def['type']]['#function_string_value_for_email'], $p_value, $p_def ); } return $p_value; } diff --git a/core/email_api.php b/core/email_api.php index 59bb51c..a947560 100644 --- a/core/email_api.php +++ b/core/email_api.php @@ -1240,7 +1240,7 @@ function email_format_bug_message( $p_visible_bug_data ) { # custom fields formatting foreach( $p_visible_bug_data['custom_fields'] as $t_custom_field_name => $t_custom_field_data ) { $t_message .= utf8_str_pad( lang_get_defaulted( $t_custom_field_name, null ) . ': ', $t_email_padding_length, ' ', STR_PAD_RIGHT ); - $t_message .= string_custom_field_value_for_email( $t_custom_field_data['value'], $t_custom_field_data['type'] ); + $t_message .= string_custom_field_value_for_email( $t_custom_field_data['value'], $t_custom_field_data ); $t_message .= " \n"; } diff --git a/core/gpc_api.php b/core/gpc_api.php index a08205a..7ae01bc 100644 --- a/core/gpc_api.php +++ b/core/gpc_api.php @@ -182,6 +182,7 @@ function gpc_isset_custom_field( $p_var_name, $p_custom_field_type ) { case CUSTOM_FIELD_TYPE_FLOAT: case CUSTOM_FIELD_TYPE_ENUM: case CUSTOM_FIELD_TYPE_EMAIL: + case CUSTOM_FIELD_TYPE_TEMPLATE: return gpc_isset( $t_field_name ) && !is_blank( gpc_get_string( $t_field_name ) ); default: return gpc_isset( $t_field_name ); diff --git a/lang/strings_dutch.txt b/lang/strings_dutch.txt index 438a89e..5d5b221 100644 --- a/lang/strings_dutch.txt +++ b/lang/strings_dutch.txt @@ -1006,7 +1006,7 @@ $s_link_custom_field_to_project_title = 'Gebruikersveld aan project koppelen'; $s_link_custom_field_to_project_button = 'Gebruikersveld koppelen'; $s_linked_projects = 'Gekoppelde projecten'; $s_custom_field_sequence = 'Volgorde'; -$s_custom_field_type_enum_string = '0:String,1:Numeriek,2:Drijvende komma,3:Enumeratie,4:E-mail,5:Checkbox,6:Lijst,7:Multiselectie lijst,8:Datum,9:Keuzerondje'; +$s_custom_field_type_enum_string = '0:String,1:Numeriek,2:Drijvende komma,3:Enumeratie,4:E-mail,5:Checkbox,6:Lijst,7:Multiselectie lijst,8:Datum,9:Keuzerondje,10:Template'; $s_confirm_used_custom_field_deletion = 'Op dit moment is dit veld verbonden met tenminste één project. Als u doorgaat, worden alle waarden voor dit veld permanent verwijderd. Deze handeling kan niet ongedaan gemaakt worden. Als u dit veld niet wilt verwijderen, klik dan op de knop "Vorige" in uw browser. Klik op onderstaande knop om door te gaan.'; $s_confirm_custom_field_deletion = 'Weet u zeker dat u dit gebruikersveld en alle bijbehorende waarden wilt verwijderen?'; $s_field_delete_button = 'Gebruikersveld verwijderen'; diff --git a/lang/strings_english.txt b/lang/strings_english.txt index bf638cb..f166eaa 100644 --- a/lang/strings_english.txt +++ b/lang/strings_english.txt @@ -1304,7 +1304,7 @@ $s_link_custom_field_to_project_button = 'Link Custom Field'; $s_linked_projects = 'Linked Projects'; $s_custom_field_sequence = 'Sequence'; -$s_custom_field_type_enum_string = '0:String,1:Numeric,2:Float,3:Enumeration,4:E-mail,5:Checkbox,6:List,7:Multiselection list,8:Date,9:Radio'; +$s_custom_field_type_enum_string = '0:String,1:Numeric,2:Float,3:Enumeration,4:E-mail,5:Checkbox,6:List,7:Multiselection list,8:Date,9:Radio,10:Template'; $s_confirm_used_custom_field_deletion = 'This field is currently linked to at least one project. If you continue all values for this field will be permanently deleted. This action cannot be undone. If you do not want to delete this field, hit the Back button in your browser. To proceed, click the button below'; $s_confirm_custom_field_deletion = 'Are you sure you want to delete this custom field and all associated values?'; -- 1.7.6.msysgit.0 | ||||
Also very interested in this. We would use this for integration with a document sharing tool like sharepoint. |
|
+1 I raised it also in the forums Few simple ideas:
|
|
No reactions? Would boosting sponsorship work? :) |
|
Thanks for the offer, but we don't typically work through sponsorships ( I guess this should be disabled ... ) . It's just a matter of time, which is not easy to find. |
|
OK, thanks for the clarification. I'd love to contribute with working on it myself, but, as you wrote, time is not easy to find :( |
|
marcin, I'd gladly add it for you, I can still occasionally find some spare time :) Feel free to contact me by email, vincent_sels@hotmail.com |
|
Vincent, thanks for the offer. I implemented a trivial fix for my needs: <pre> * 1272,1277 ** NOTE: This probably belongs in the string_api.php
(ARGH, pasting code in doesn't work ideally, see the attached patch) This allows me converting all numeric ids contained in this field into links, additionally in bold as it's important. So, I'm content for now, and I can hack it any way I want. But I still think it would be nice to have as an official plugin/feature. But that's way more work, esp. configuration. If it's done by someone, my sponsorship still holds :) |
|
Created pull request https://github.com/mantisbt/mantisbt/pull/41 that adds this. Screenshots: Field definition: http://grab.by/bPp0 Feel free to test it and if you encounter any issues, I'll immediately take a look at them. |
|
I've deleted trivial.patch based on Marcin's request. |
|
Btw, we discussed it with Vincent offline. His change is nice, but another idea popped up. We could add two attributes to all custom fields:
This way, we keep it generic and allow more stuff. For example, in our system we have a custom "Fixed in branch" field which is now a multi-choice. If it was extended with the template mechanism, the choices (branch names) could be converted into links automatically on display. But perhaps it's an overkill :) |
|
Changed the target version to 1.3.x. This is a feature and should therefore land in a feature branch -- not the 1.2.x maintenance branch. |
|
Confirmed, makes sense to have this. |
|
This seems like a useful feature that should probably make it into master now to make it into the 1.3.x release train which is currently in beta. Will this template model support showing a hyperlinked text or image? This would provide a clean look for long URLs (e.g. value 1234 becomes "1234" hyperlinked). Such values are cleaner looking and can fit nicely in View Issues page. |
|
This functionality could be done with a plugin attached is an example plugin: It creates a new column, that outputs an url using another custom field as source for some of its parameters. One possible problem. This can define only one column for each class defined in source. Not valid for runtime configuration of new templated columns? template_column_test.php (1,660 bytes)
<?php class CustomColumn extends MantisColumn { public $title = 'column_test'; public $column = 'column_test'; public $source_field = 'source_custom_field_name'; function display( BugData $p_bug, $p_columns_target ){ $t_field_id = custom_field_get_id_from_name( $this->source_field ); $t_value= custom_field_get_value( $t_field_id, $p_bug->id ); echo '<a href="http://example.com?val=' . $t_value . '">' . $t_value . '</a>'; } } class template_column_testPlugin extends MantisPlugin { /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ function register() { $this->name = 'template_column_test'; # Proper name of plugin $this->description = 'template_column_test'; # Short description of the plugin $this->version = '1.0'; # Plugin version string $this->requires = array( # Plugin dependencies, array of basename => version pairs 'MantisCore' => '1.3.0', # Should always depend on an appropriate version of MantisBT ); $this->author = 'carlos proensa'; # Author/team name $this->contact = ''; # Author/team e-mail address $this->url = ''; # Support webpage } function hooks( ) { $hooks = array( 'EVENT_FILTER_COLUMNS' => 'register_column', ); return $hooks; } function register_column( $p_event ) { return array ( 'CustomColumn' ); } } |
|
opened 0020140 for a fix |
|