diff --git a/CHANGELOG.md b/CHANGELOG.md index d30264d..b58c58a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ ## Scrum plugin Revision History +### V0.4 - 2017-12-21 + +* Add settings page, there also save, change values. +* Rewrite of settings default, so that is easier to save it. +* Add function to save settings without redundant source. +* Clean up stylesheets for scrum overview. +* Each Issue on the Scrum Board use his status color to more illustrate. +* Fix different source topics. +* Add Status view, each first string of the status, to the issue. + ### v0.3 - 2014-11-10 + - Configuration page - Fall back to default color for undefined severity/resolution - Board column headers can now be localized diff --git a/README.md b/README.md index 1ec536c..1698423 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Scrum Board plugin for MantisBT Copyright (c) 2011 - 2012 John Reese - http://noswap.com -Copyright (c) 2012 - 2014 MantisBT Team - mantisbt-dev@lists.sourceforge.net +Copyright (c) 2012 - 2018 MantisBT Team - mantisbt-dev@lists.sourceforge.net Released under the [MIT license](http://opensource.org/licenses/MIT) @@ -13,15 +13,19 @@ See the [Changelog](https://github.com/mantisbt-plugins/scrum/blob/config/CHANGE Adds a Scrum board based on Status, Category, and Target Version to MantisBT. +![MantisBT Scrum Board page](./scrum-plugin-board.png) + ## Requirements -The plugin requires [MantisBT](http://www.mantisbt.org/) version 1.2.6 or higher. +The plugin requires [MantisBT](http://www.mantisbt.org/) version 1.2.6 or higher and PHP 5.6. If the [Source Integration plugin](https://github.com/mantisbt-plugins/source-integration) (version 0.16 or higher) is installed, the cards will display the number of changesets attached to each issue. +The plugin is currently only tested with MantisBT 1.2*. + ## Installation @@ -32,6 +36,7 @@ changesets attached to each issue. *Manage -> Manage Plugins*. 4. In the *Available Plugins* list, you'll find the *Scrum* plugin; click the **Install** link. +5. All settings are available after click on the plugin in the Plugin list. ## Usage diff --git a/Scrum/Scrum.php b/Scrum/Scrum.php index 9ec263c..65d1944 100644 --- a/Scrum/Scrum.php +++ b/Scrum/Scrum.php @@ -1,10 +1,10 @@ name = plugin_lang_get("title"); - $this->description = plugin_lang_get("description"); - $this->page = 'config_page'; + public function register() { + + $this->name = plugin_lang_get( 'title' ); + $this->description = plugin_lang_get( 'description' ); + $this->page = 'config_page'; - $this->version = "0.3"; + $this->version = '0.4'; $this->requires = array( - "MantisCore" => "1.2.6", + 'MantisCore' => '1.2.6', ); - $this->uses = array( - "Source" => "0.16", + $this->uses = array( + 'Source' => '0.16', ); - $this->author = "John Reese"; - $this->contact = "john@noswap.com"; - $this->url = "https://github.com/mantisbt-plugins/scrum"; + $this->author = 'John Reese'; + $this->contact = 'john@noswap.com'; + $this->url = 'https://github.com/mantisbt-plugins/scrum'; } - public function config() - { + public function config() { + return array( #$g_status_enum_string = '10:new,20:feedback,30:acknowledged,40:confirmed,50:assigned,80:resolved,90:closed'; - "board_columns" => array( - "new" => array(10, 20, 30), - "confirmed" => array(40, 50), - "resolved" => array(80), + 'board_columns' => array( + 'new' => array( 10, 20, 30 ), + 'confirmed' => array( 40, 50, 85 ), + 'resolved' => array( 80, 88 ), ), #$g_severity_enum_string = '10:feature,20:trivial,30:text,40:tweak,50:minor,60:major,70:crash,80:block'; - "board_severity_colors" => array( - 10 => "green", - 20 => "green", - 30 => "green", - 40 => "green", - 50 => "gray", - 60 => "gray", - 70 => "orange", - 80 => "red", + 'board_severity_colors' => array( + 10 => 'green', + 20 => 'green', + 30 => 'green', + 40 => 'green', + 50 => 'gray', + 60 => 'gray', + 70 => 'orange', + 80 => 'red', ), #$g_resolution_enum_string = '10:open,20:fixed,30:reopened,40:unable to duplicate,50:not fixable,60:duplicate,70:not a bug,80:suspended,90:wont fix'; - "board_resolution_colors" => array( - 10 => "orange", - 20 => "green", - 30 => "red", - 40 => "gray", - 50 => "gray", - 60 => "gray", - 70 => "gray", - 80 => "gray", - 90 => "gray", + 'board_resolution_colors' => array( + 10 => 'orange', + 20 => 'green', + 30 => 'red', + 40 => 'gray', + 50 => 'gray', + 60 => 'gray', + 70 => 'gray', + 80 => 'gray', + 90 => 'gray', ), - "token_expiry" => 30 * ScrumPlugin::DURATION_DAY, - "sprint_length" => 14 * ScrumPlugin::DURATION_DAY, - "show_empty_status" => OFF, + 'token_expiry' => 30, + 'board_sprint_length' => 14, + 'show_empty_status' => false, ); } - public function hooks() - { + public function hooks() { + return array( - "EVENT_MENU_MAIN" => "menu", + 'EVENT_MENU_MAIN' => 'menu', ); } - public function menu($event) - { - $links = array(); - $links[] = '' . plugin_lang_get("board") . ''; + public function menu() { + + $links = array(); + $links[] = '' . plugin_lang_get( 'board' ) . ''; return $links; } + + /** + * Set configuration option, if different to the current value. + * + * @param $option string Name of the option inside the database. + * @param $value mixed Value of the option. + * + * @return bool True if is changed and false, no change necessary. + */ + public function config_set( $option, $value ) { + + if ( plugin_config_get( $option ) !== $value ) { + plugin_config_set( $option, $value ); + return true; + } + + return false; + } } diff --git a/Scrum/files/scrumboard.css b/Scrum/files/scrumboard.css index a6cb8e0..6edcffe 100644 --- a/Scrum/files/scrumboard.css +++ b/Scrum/files/scrumboard.css @@ -19,10 +19,13 @@ div.scrumbar span { } div.scrumbar span.bar { - padding: 0.5em 0em; + padding: 0.5em 0; background: #d2f5b0; } +table.scrumboard { +} + td.scrumcolumn { padding: 4px; vertical-align: top; @@ -31,7 +34,7 @@ td.scrumcolumn { td.scrumcolumn hr { clear: both; border: 0; - border-bottom: 1px dotted #aaa; + border-bottom: 2px dotted #f4f4f4; height: 6px; } @@ -39,10 +42,7 @@ div.scrumblock { float: left; width: 230px; margin: 4px; - - background: #FAF3AA; border: 1px solid black; - text-align: center; overflow: hidden; } @@ -63,14 +63,23 @@ div.scrumblock p.commits { div.scrumblock p.category { font-weight: bold; + height: 1.4em; + overflow: hidden; +} + +div.scrumblock p.status { + float: right; + width: 1.2em; + height: 1.2em; + border: 1px solid black; } div.scrumblock p.summary { clear: both; width: 100%; height: 5em; - border-top: 1px solid #e7df8a; - border-bottom: 1px solid #e7df8a; + border-top: 1px solid #f4f4f4; + border-bottom: 1px solid #f4f4f4; padding-top: 3px; text-align: left; overflow: hidden; diff --git a/Scrum/lang/strings_english.txt b/Scrum/lang/strings_english.txt index 296a46b..aef577a 100644 --- a/Scrum/lang/strings_english.txt +++ b/Scrum/lang/strings_english.txt @@ -1,6 +1,6 @@ %s'; $s_plugin_Scrum_board_severity_colors_label = 'Board Severity Colors'; $s_plugin_Scrum_board_resolution_colors_label = 'Board Resolution Colors'; $s_plugin_Scrum_color = 'Color'; -$s_plugin_Scrum_colors_info = 'Define the colors assigned to each %s, as a comma-delimited list of elements with the form <Code:Color>.
Note: undefined codes will display in white on the Cards. You can either use standard CSS color names or hex values.'; -$s_plugin_Scrum_sprint_length_label = 'Sprint Length'; -$s_plugin_Scrum_sprint_length_info = 'The duration of the Sprint in days'; +$s_plugin_Scrum_colors_info = 'Define the colors assigned to each %s, as a comma-delimited list of elements with the form "Code":"Color".
Note: undefined codes will display in white on the Cards. You can either use standard CSS color names or hex values.'; +$s_plugin_Scrum_board_sprint_length_label = 'Sprint Length'; +$s_plugin_Scrum_board_sprint_length_info = 'The duration of the Sprint in days'; $s_plugin_Scrum_show_empty_status_label = 'Always show Status'; $s_plugin_Scrum_show_empty_status_info = 'If checked, the Status is displayed even if does not contain any Cards'; $s_plugin_Scrum_token_expiry_label = 'Token Expiry'; diff --git a/Scrum/pages/board.php b/Scrum/pages/board.php index e67cb99..642aef0 100644 --- a/Scrum/pages/board.php +++ b/Scrum/pages/board.php @@ -1,216 +1,227 @@ getConstants(); + +// Set to an var. +$token_versions_by_project = (string) token_get_value( $scrum_plugin_constants[ 'TOKEN_SCRUM_VERSION' ] ); +if ( null !== $token_versions_by_project ) { $versions_by_project = unserialize( $token_versions_by_project ); } -if( gpc_isset( 'version' ) ) { +if ( gpc_isset( 'version' ) ) { $target_version = gpc_get_string( 'version', '' ); } else { - if( array_key_exists( $current_project, $versions_by_project) ) { - $target_version = $versions_by_project[$current_project]; + if ( array_key_exists( $current_project, $versions_by_project ) ) { + $target_version = $versions_by_project[ $current_project ]; } } -if( !in_array( $target_version, $versions ) ) { +if ( ! in_array( $target_version, $versions, false ) ) { $target_version = ''; } -$versions_by_project[$current_project] = $target_version; -$t_res = token_set( - ScrumPlugin::TOKEN_SCRUM_VERSION, +$versions_by_project[ $current_project ] = $target_version; +$t_res = token_set( + $scrum_plugin_constants[ 'TOKEN_SCRUM_VERSION' ], serialize( $versions_by_project ), - plugin_config_get( 'token_expiry' ) + plugin_config_get( 'token_expiry' ) * $scrum_plugin_constants[ 'DURATION_DAY' ] ); # Fetch list of categories in use for the given projects $params = array(); +/** @noinspection SqlDialectInspection */ +/** @noinspection SqlNoDataSourceInspection */ $query = "SELECT DISTINCT category_id FROM {$bug_table} - WHERE project_id IN (" . join( ', ', $project_ids ) . ") "; + WHERE project_id IN (" . implode( ', ', $project_ids ) . ') '; -if( $target_version ) { - $query .= "AND target_version=" . db_param(); +if ( $target_version ) { + $query .= 'AND target_version=' . db_param(); $params[] = $target_version; } -$result = db_query_bound( $query, $params ); -$categories = array(); -$category_ids = array(); +$result = db_query_bound( $query, $params ); +$categories = array(); +$category_ids = array(); $category_name = null; -while( $row = db_fetch_array( $result ) ) { - $category_id = $row['category_id']; +while ( $row = db_fetch_array( $result ) ) { + $category_id = $row[ 'category_id' ]; $category_ids[] = $category_id; - $category_name = category_full_name( $category_id, false ); + $category_name = category_full_name( $category_id, false ); - if( isset( $categories[$category_name] ) ) { - $categories[$category_name][] = $category_id; + if ( isset( $categories[ $category_name ] ) ) { + $categories[ $category_name ][] = $category_id; } else { - $categories[$category_name] = array( $category_id ); + $categories[ $category_name ] = array( $category_id ); } } # Get the selected category -$categories_by_project = array(); -$token_categories_by_project = token_get_value( ScrumPlugin::TOKEN_SCRUM_CATEGORY ); +$categories_by_project = array(); +$token_categories_by_project = (string) token_get_value( $scrum_plugin_constants[ 'TOKEN_SCRUM_CATEGORY' ] ); -if( !is_null( $token_categories_by_project ) ) { +if ( null !== $token_categories_by_project ) { $categories_by_project = unserialize( $token_categories_by_project ); } -if( gpc_isset( 'category' ) ) { +if ( gpc_isset( 'category' ) ) { $category = gpc_get_string( 'category', '' ); } else { - if( array_key_exists( $current_project, $categories_by_project) ) { - $category = $categories_by_project[$current_project]; + if ( array_key_exists( $current_project, $categories_by_project ) ) { + $category = $categories_by_project[ $current_project ]; } } -if( isset( $categories[$category] ) ) { - $category_ids = $categories[$category]; +if ( isset( $categories[ $category ] ) ) { + $category_ids = $categories[ $category ]; } -$columns = plugin_config_get( 'board_columns' ); -$sevcolors = plugin_config_get( 'board_severity_colors' ); -$rescolors = plugin_config_get( 'board_resolution_colors' ); -$sprint_length = plugin_config_get( 'sprint_length' ); +$columns = plugin_config_get( 'board_columns' ); +$sevcolors = plugin_config_get( 'board_severity_colors' ); +$rescolors = plugin_config_get( 'board_resolution_colors' ); +$sprint_length = plugin_config_get( 'board_sprint_length' ) * $scrum_plugin_constants[ 'DURATION_DAY' ]; # Retrieve all statuses to display on the board $statuses = array(); -foreach( $columns as $col ) { +foreach ( $columns as $col ) { $statuses = array_merge( $statuses, $col ); } -$categories_by_project[$current_project] = $category; +$categories_by_project[ $current_project ] = $category; token_set( - ScrumPlugin::TOKEN_SCRUM_CATEGORY, - serialize( $categories_by_project), - plugin_config_get( 'token_expiry' ) + $scrum_plugin_constants[ 'TOKEN_SCRUM_CATEGORY' ], + serialize( $categories_by_project ), + plugin_config_get( 'token_expiry' ) * $scrum_plugin_constants[ 'DURATION_DAY' ] ); # Retrieve all bugs with the matching target version $params = array(); +/** @noinspection SqlNoDataSourceInspection */ $query = "SELECT id FROM {$bug_table} - WHERE project_id IN (" . join( ', ', $project_ids ) . ') - AND status IN (' . join( ', ', $statuses ) . ')'; + WHERE project_id IN (" . implode( ', ', $project_ids ) . ') + AND status IN (' . implode( ', ', $statuses ) . ')'; -if( $target_version ) { - $query .= " AND target_version=" . db_param(); +if ( $target_version ) { + $query .= ' AND target_version=' . db_param(); $params[] = $target_version; } -if( $category_name ) { - $query .= " AND category_id IN (" . join( ', ', $category_ids ) . ")"; +if ( $category_name ) { + $query .= ' AND category_id IN (' . implode( ', ', $category_ids ) . ")"; } -$query .= ' ORDER BY status ASC, priority DESC, id DESC'; -$result = db_query_bound($query, $params); +$query .= ' ORDER BY status ASC, priority DESC, id DESC'; +$result = db_query_bound( $query, $params ); $bug_ids = array(); -while( $row = db_fetch_array( $result ) ) { - $bug_ids[] = $row['id']; +while ( $row = db_fetch_array( $result ) ) { + $bug_ids[] = $row[ 'id' ]; } bug_cache_array_rows( $bug_ids ); -$bugs = array(); +$bugs = array(); $status = array(); -$use_source = plugin_is_loaded( 'Source' ); +$use_source = plugin_is_loaded( 'Source' ); $resolved_count = 0; -foreach( $bug_ids as $bug_id ) { - $bug = bug_get( $bug_id ); - $bugs[$bug->status][] = $bug; +foreach ( $bug_ids as $bug_id ) { + $bug = bug_get( $bug_id ); + $bugs[ $bug->status ][] = $bug; - $source_count[$bug_id] = $use_source + $source_count[ $bug_id ] = $use_source ? count( SourceChangeset::load_by_bug( $bug_id ) ) - : '' ; - if( $bug->status >= $resolved_threshold ) { - $resolved_count++; + : ''; + if ( $bug->status >= $resolved_threshold ) { + $resolved_count ++; } } $bug_count = count( $bug_ids ); -if( $bug_count > 0 ) { +if ( $bug_count > 0 ) { $resolved_percent = floor( 100 * $resolved_count / $bug_count ); $bug_percentage_by_column = array(); - foreach( $columns as $column => $statuses ) { + foreach ( $columns as $column => $statuses ) { $bug_count_for_column = 0; - foreach( $statuses as $l_status ) { - if( array_key_exists( $l_status, $bugs ) ) { - $bug_count_for_column += count( $bugs[$l_status] ); + foreach ( (array) $statuses as $l_status ) { + if ( array_key_exists( $l_status, $bugs ) ) { + $bug_count_for_column += count( $bugs[ $l_status ] ); } } - $bug_percentage_by_column[$column] = $bug_count_for_column / $bug_count * 100; + $bug_percentage_by_column[ $column ] = $bug_count_for_column / $bug_count * 100; } } else { - $resolved_percent = 0; + $resolved_percent = 0; $bug_percentage_by_column = 100 / count( $columns ); } -if( $target_version ) { - foreach( $project_ids as $project_id ) { +if ( $target_version ) { + foreach ( $project_ids as $project_id ) { $version_id = version_get_id( $target_version, $project_id, true ); - if( $version_id !== false ) { + if ( $version_id !== false ) { break; } } - $version = version_get( $version_id ); - $time_diff = max( 0, $version->date_order - time() ); + $version = version_get( $version_id ); + $time_diff = max( 0, $version->date_order - time() ); $timeleft_percent = 100 - min( 100, 100 * $time_diff / $sprint_length ); - if( $time_diff >= ( 2 * ScrumPlugin::DURATION_WEEK ) ) { + if ( $time_diff >= ( 2 * $scrum_plugin_constants[ 'DURATION_WEEK' ] ) ) { $timeleft_string = sprintf( plugin_lang_get( 'time_weeks' ), - floor( $time_diff / ScrumPlugin::DURATION_WEEK ) + floor( $time_diff / $scrum_plugin_constants[ 'DURATION_WEEK' ] ) ); - } elseif( $time_diff >= ( 2 * ScrumPlugin::DURATION_DAY ) ) { + } elseif ( $time_diff >= ( 2 * $scrum_plugin_constants[ 'DURATION_DAY' ] ) ) { $timeleft_string = sprintf( plugin_lang_get( 'time_days' ), - floor( $time_diff / ScrumPlugin::DURATION_DAY ) + floor( $time_diff / $scrum_plugin_constants[ 'DURATION_DAY' ] ) ); - } elseif( $time_diff > ScrumPlugin::DURATION_HOUR ) { + } elseif ( $time_diff > $scrum_plugin_constants[ 'DURATION_HOUR' ] ) { $timeleft_string = sprintf( plugin_lang_get( 'time_hours' ), - floor( $time_diff / ScrumPlugin::DURATION_HOUR ) + floor( $time_diff / $scrum_plugin_constants[ 'DURATION_HOUR' ] ) ); - } elseif( $time_diff > 0 ) { + } elseif ( $time_diff > 0 ) { $timeleft_string = plugin_lang_get( 'time_1hour' ); } else { $timeleft_string = plugin_lang_get( 'time_up' ); @@ -220,165 +231,166 @@ html_page_top( plugin_lang_get( 'board' ) ); ?> - - -
- - - - - - - - - - +
- -
- - - - - - - -
-
-
- 50 ): ?> - - -   - -
- - -
- 50 ): ?> - + + +
+ + + + + + + + + + - - - - - $statuses ): ?> - - - - - - - $statuses ) { -?> - + + + + + $statuses ): ?> + + + + + + + $statuses ) { + $first = true; + ?> + - + ?> + + - -
+ +
+ + + + + + + +
+
+
+ 50 ): ?> + + +   + + +
+ + +
+ 50 ): ?> + + +   + + +
-   +
+ + +
- - -
- - -
- -
- -
- -

- -

severity, $sevcolors ) - ? $sevcolors[$bug->severity] - : 'white' ; - $rescolor = array_key_exists( $bug->resolution, $rescolors ) - ? $rescolors[$bug->resolution] - : 'white' ; -?> -
-

priority ) ?>

-

-

id] ?>

-

project_id != $current_project ) { - $project_name = project_get_name( $bug->project_id ); - echo '' . $project_name . ' - '; - } - echo category_full_name( $bug->category_id, false ) ?> -

-

+

id ) - . ': ' - . bug_format_summary( $bug->id, 0 ); - ?> -

-

-

-

-

-

handler_id > 0 ? user_get_name( $bug->handler_id ) : '' - ?>

- -'; + } + + # Display status name only if different from column header + $column_enum_val = MantisEnum::getValue( $status_enum, $column ); + + if ( $column_enum_val !== $status ) { + ?> +

+ +

severity, $sevcolors ) + ? $sevcolors[ $bug->severity ] + : 'white'; + $rescolor = array_key_exists( $bug->resolution, $rescolors ) + ? $rescolors[ $bug->resolution ] + : 'white'; + $status_color = get_status_color( $bug->status, auth_get_current_user_id(), $bug->project_id ); + $status_string = get_enum_element( 'status', $bug->status ); + ?> +
+

priority ) ?>

+

+

project_id !== $current_project ) { + $project_name = project_get_name( $bug->project_id ); + echo '' . $project_name . ' - '; + } + echo category_full_name( $bug->category_id, false ) ?> +

+

+ id ) + . ': ' + . bug_format_summary( $bug->id, 0 ); + ?> + +

+

+

+

+

+

handler_id > 0 ? user_get_name( $bug->handler_id ) : '' + ?>

+
+ -
+
array(). +$t_board_columns = array( + $t_field_col[ 0 ] => array_map( 'intval', explode( ',', $t_field_status[ 0 ] ) ), + $t_field_col[ 1 ] => array_map( 'intval', explode( ',', $t_field_status[ 1 ] ) ), + $t_field_col[ 2 ] => array_map( 'intval', explode( ',', $t_field_status[ 2 ] ) ), +); +$scrum = new ScrumPlugin( __FILE__ ); +// Set new value, if different. +$scrum->config_set( 'board_columns', $t_board_columns ); + +/** + * Get the board_severity_colors values. + */ +$t_field_colors = gpc_get_string( 'board_severity_colors' ); +// Build array for 'board_severity_colors'. +$t_field_colors = (array) json_decode( '{' . $t_field_colors . '}' ); +$tmp_field_colors = array(); +foreach ( $t_field_colors as $status => $color ) { + $tmp_field_colors[ $status ] = $color; +} +// Set new value, if different. +$scrum->config_set( 'board_severity_colors', $tmp_field_colors ); + +/** + * Get the board_resolution_colors values. + */ +$t_resolution_colors = gpc_get_string( 'board_resolution_colors' ); +// Build array for 'board_resolution_colors'. +$t_resolution_colors = (array) json_decode( '{' . $t_resolution_colors . '}' ); +$tmp_resolution_colors = array(); +foreach ( $t_resolution_colors as $status => $color ) { + $tmp_resolution_colors[ $status ] = $color; +} +// Set new value, if different. +$scrum->config_set( 'board_resolution_colors', $tmp_resolution_colors ); + +/** + * Get the board_sprint_length. + */ +$t_sprint_length = gpc_get_int( 'board_sprint_length' ); +// Set new value, if different. +$scrum->config_set( 'board_sprint_length', $t_sprint_length ); + +/** + * Get show_empty_status and set the new value. + * Set always to false, if is not in $_POST. + * + */ +if ( isset( $_POST[ 'show_empty_status' ] ) ) { + $t_show_empty_status = gpc_get_bool( 'show_empty_status' ); + // Set new value, if different. + $scrum->config_set( 'show_empty_status', $t_show_empty_status ); +} else { + $scrum->config_set( 'show_empty_status', false ); +} + +/** + * Get the token for expire the filter criteria. + */ +$t_token_expiry = gpc_get_int( 'token_expiry' ); +// Set new value, if different. +$scrum->config_set( 'token_expiry', $t_token_expiry ); + +print_successful_redirect( plugin_page( 'config_page', true ) ); \ No newline at end of file diff --git a/Scrum/pages/config_page.php b/Scrum/pages/config_page.php index 5329b63..3f5fc3a 100644 --- a/Scrum/pages/config_page.php +++ b/Scrum/pages/config_page.php @@ -1,6 +1,6 @@ -
-
- - +
+ + +
- - - - - - -> - - - + + + > + + + - - -> - - - + + + > + + + - - -> - - - + + + > + + + - - -> - - - + + + > + + + - - -> - - - + + + > + + + - - -> - - - + + + > + + + - - - + + + -
-
- -
- - - - + + - $t_value ) { - echo ''; - echo ''; - echo ''; - echo ''; - } -?> -
- -
+ + + + + + + + $t_value ) { + echo ''; + echo ''; + echo ''; + echo ''; + } + ?> +
+ +
-
- - -
-
- -
+ + + +
+ + +
-
- - -
-
- -
+ + + +
+ +
-
- -
- -
+ + + +
-
- -
- > -
+ + + > +
-
- -
- -
+ + + +
"/>
+ +
-
+ +