View Issue Details

IDProjectCategoryView StatusLast Update
0024416mantisbtupgradepublic2018-07-30 03:44
Reporteraberaza86Assigned Todregad 
PriorityimmediateSeveritycrashReproducibilityalways
Status closedResolutionfixed 
PlatformOSWindowsOS Version10
Product Version2.14.0 
Target Version2.16.0Fixed in Version2.16.0 
Summary0024416: Improve handling of unserialize errors when upgrading
Description

I need help to migrate the Mantis 1.0.8 that my current company has to the latest version of 2.14.0.
The current Mantis 1.0.8 is under windows 10. with an apache server, my sql and php.
and the new mantis 2.14.0 want to leave it under the same systems.
I downloaded the xampp, with the apache, mysql and php.
make a backup of the old mantis bases, and when I want to install the new mantis to use the previously backed base.
I get the following error in the installation:
SYSTEM NOTICE: 'unserialize (): Error at offset 0 of 51 bytes' in 'C: \ xampp \ htdocs \ mantisbt \ core \ install_helper_functions_api.php' line 657

Someone could help me. to know well how should I do the migration, or how can I solve the error that it gives me?
many thanks

Alguien me podria ayudar. para saber bien como debo hacer la migracion, o como puedo solucionar el error que me da?
muchisimas gracias

TagsNo tags attached.

Relationships

related to 0021312 confirmed Error Schema step 193 - Upgrading 1.2.19 to 1.3.0 
has duplicate 0024419 closedatrol Error in migration from mantis 1.0.8 to 2.14 
has duplicate 0024488 closedatrol need help to migrate the Mantis 1.0.8 that my current company has to the latest version of 2.14.0. 

Activities

atrol

atrol

2018-05-10 13:22

developer   ~0059758

Please attach the output of the following SQL statement to the issue
SELECT * FROM mantis_config_table WHERE type=3;

aberaza86

aberaza86

2018-05-10 13:38

reporter   ~0059759

Results



Error_mantis.xlsx (11,051 bytes)
atrol

atrol

2018-05-10 13:59

developer   ~0059761

Delete the first two rows (the ones with project_id 148)
After that, run again the installer

aberaza86

aberaza86

2018-05-10 15:07

reporter   ~0059762

I eliminated the first 2 rows and ran the installation again, but I still get the same error.



error_mantis_2.jpg (45,846 bytes)
error_mantis_2.jpg (45,846 bytes)
aberaza86

aberaza86

2018-05-10 15:14

reporter   ~0059763

in the same way, pressing the button to return to the administration, in the upper right part. it allows me to enter the incident screen and I can see them. But at the top it gives me an error, and when wanting to open a created incident, it gives me another worse error that does not let me see it.



error_mantis_4.jpg (279,983 bytes)
error_mantis_4.jpg (279,983 bytes)
error_mantis_5.jpg (96,649 bytes)
error_mantis_5.jpg (96,649 bytes)
atrol

atrol

2018-05-10 17:08

developer   ~0059764

but I still get the same error.

It's not exactly the same error.
It's caused by another row in database.

You shouldn't go on using the system as long as there is a problem when upgrading.
Depending on what you are doing, you are introducing subsequent defects.
I hope you made a database backup before you started the upgrade, as we will have to start from scratch after having found all root causes of the upgrade problems.

What's now the output of SELECT * FROM mantis_config_table WHERE type=3; ?

aberaza86

aberaza86

2018-05-11 07:31

reporter   ~0059768

ok, now I get this errors



Error_mantis_2.xlsx (10,973 bytes)
dregad

dregad

2018-05-11 10:25

developer   ~0059769

The first line (status_enum_workflow) is causing the error. Apparently, every time a á is present in the string (e.g. "se necesitan más datos") , the count of characters is off by 1 (e.g. 85 instead of 86 for the first occurence). Not sure what the root cause for that is. You probably want to manually fix that; alternatively you can simply remove the row, but then you will have to manually define the workflow again.

aberaza86

aberaza86

2018-05-11 10:59

reporter   ~0059770

I modified the value and subscribed the spaces and accents. (se necesitan más datos > se_necesitan_mas_datos). Now I get the following error:



error_mantis_6.jpg (53,381 bytes)
error_mantis_6.jpg (53,381 bytes)
aberaza86

aberaza86

2018-05-14 08:29

reporter   ~0059783

Please. I need help.

dregad

dregad

2018-05-15 07:27

developer   ~0059796

@aberaza86 please have a look at the following, work-in-progress branch - it modifies the installer to abort more gracefully when upgrade steps 193, 194 and 195 fail because of invalid serialized data; It will identify the offending row, then you can take appropriate action to fix or delete it. This would be an iterative process, i.e. you have to re-run the upgrade until there are no more errors.

https://github.com/dregad/mantisbt/tree/install-unserialize

Let me know how it goes.

aberaza86

aberaza86

2018-05-15 10:38

reporter   ~0059803

Last edited: 2018-05-15 10:39

View 2 revisions

I realize this:

UPGRADING

  • Backup your existing installation and database -- really!
  • Extract the tarball into a clean directory; do not extract into an existing installation, as some files have been moved or deleted between releases
  • Copy your configuration from the old installation to the new directory, including config_inc.php, custom_strings_inc.php, custom_relationships_inc.php,
    custom_functions_inc.php and custom_constants_inc.php if they exist
  • Point your browser to http://path/to/mantisbt/admin/check/index.php to ensure that your webserver is compatible with MantisBT and configured
    correctly.

    And this are the results:

Warning: Use of undefined constant PHP_MIN_VERSION - assumed 'PHP_MIN_VERSION' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\core.php on line 70

Warning: Use of undefined constant PHPMAILER_METHOD_MAIL - assumed 'PHPMAILER_METHOD_MAIL' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 630

Warning: Use of undefined constant POSITION_BOTTOM - assumed 'POSITION_BOTTOM' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1195

Warning: Use of undefined constant REPRODUCIBILITY_HAVENOTTRIED - assumed 'REPRODUCIBILITY_HAVENOTTRIED' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1456

Warning: Use of undefined constant PROJECTION_NONE - assumed 'PROJECTION_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1462

Warning: Use of undefined constant ETA_NONE - assumed 'ETA_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1468

Warning: Use of undefined constant BUG_REL_NONE - assumed 'BUG_REL_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1474

Warning: Use of undefined constant UNABLE_TO_REPRODUCE - assumed 'UNABLE_TO_REPRODUCE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1715

Warning: Use of undefined constant LINKS_SAME_WINDOW - assumed 'LINKS_SAME_WINDOW' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1971

Warning: Use of undefined constant TOKEN_EXPIRY_AUTHENTICATED - assumed 'TOKEN_EXPIRY_AUTHENTICATED' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 2028

Warning: Use of undefined constant UNABLE_TO_REPRODUCE - assumed 'UNABLE_TO_REPRODUCE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 2234

Warning: Use of undefined constant AUTH_PAGE_USERNAME - assumed 'AUTH_PAGE_USERNAME' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 3510

Warning: Use of undefined constant ASCENDING - assumed 'ASCENDING' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 3730

Warning: Use of undefined constant DESCENDING - assumed 'DESCENDING' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 3731

Warning: Use of undefined constant DISPLAY_ERROR_HALT - assumed 'DISPLAY_ERROR_HALT' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4257

Warning: Use of undefined constant DISPLAY_ERROR_HALT - assumed 'DISPLAY_ERROR_HALT' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4258

Warning: Use of undefined constant DISPLAY_ERROR_INLINE - assumed 'DISPLAY_ERROR_INLINE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4259

Warning: Use of undefined constant LOG_NONE - assumed 'LOG_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4301
Possible Whitespace/Error in Configuration File - Aborting. Output so far follows:
string(4046) "
Warning: Use of undefined constant PHPMAILER_METHOD_MAIL - assumed 'PHPMAILER_METHOD_MAIL' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 630

Warning: Use of undefined constant POSITION_BOTTOM - assumed 'POSITION_BOTTOM' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1195

Warning: Use of undefined constant REPRODUCIBILITY_HAVENOTTRIED - assumed 'REPRODUCIBILITY_HAVENOTTRIED' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1456

Warning: Use of undefined constant PROJECTION_NONE - assumed 'PROJECTION_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1462

Warning: Use of undefined constant ETA_NONE - assumed 'ETA_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1468

Warning: Use of undefined constant BUG_REL_NONE - assumed 'BUG_REL_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1474

Warning: Use of undefined constant UNABLE_TO_REPRODUCE - assumed 'UNABLE_TO_REPRODUCE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1715

Warning: Use of undefined constant LINKS_SAME_WINDOW - assumed 'LINKS_SAME_WINDOW' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 1971

Warning: Use of undefined constant TOKEN_EXPIRY_AUTHENTICATED - assumed 'TOKEN_EXPIRY_AUTHENTICATED' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 2028

Warning: Use of undefined constant UNABLE_TO_REPRODUCE - assumed 'UNABLE_TO_REPRODUCE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 2234

Warning: Use of undefined constant AUTH_PAGE_USERNAME - assumed 'AUTH_PAGE_USERNAME' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 3510

Warning: Use of undefined constant ASCENDING - assumed 'ASCENDING' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 3730

Warning: Use of undefined constant DESCENDING - assumed 'DESCENDING' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 3731

Warning: Use of undefined constant DISPLAY_ERROR_HALT - assumed 'DISPLAY_ERROR_HALT' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4257

Warning: Use of undefined constant DISPLAY_ERROR_HALT - assumed 'DISPLAY_ERROR_HALT' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4258

Warning: Use of undefined constant DISPLAY_ERROR_INLINE - assumed 'DISPLAY_ERROR_INLINE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4259

Warning: Use of undefined constant LOG_NONE - assumed 'LOG_NONE' (this will throw an Error in a future version of PHP) in C:\xampp\htdocs\mantisbt-2\config_defaults_inc.php on line 4301
"

aberaza86

aberaza86

2018-05-15 10:43

reporter   ~0059804

Now I replaced the file "C: \ xampp \ htdocs \ mantisbt-2 \ config_defaults_inc.php" with the one of the previous installation of mantis and when updating the page it gives me the following errors:

Warning: ob_start(): function 'compress_handler' not found or invalid function name in C:\xampp\htdocs\mantisbt-2\core.php on line 18

Notice: ob_start(): failed to create buffer in C:\xampp\htdocs\mantisbt-2\core.php on line 18

Warning: require_once(C:\xampp\htdocs\mantisbt-2\core\timer_api.php): failed to open stream: No such file or directory in C:\xampp\htdocs\mantisbt-2\core.php on line 90

Fatal error: require_once(): Failed opening required 'C:\xampp\htdocs\mantisbt-2\core\timer_api.php' (include_path='C:\xampp\php\PEAR') in C:\xampp\htdocs\mantisbt-2\core.php on line 90

Rost

Rost

2018-05-15 10:47

reporter   ~0059805

Last edited: 2018-05-15 12:44

View 3 revisions

@aberaza86: I yesterday made a migration from much newer than yours 1.2.5 to 1.3.15 with moving to new PHP (7.0). WIth direct migration I had some strange errors, please, find 30 minutes and do my long sequence:

  • download and install XAMP with OLD PHP related to something around 5.3
  • download several versions: 1.0.8 (your initial), 1.2.0, 1.2.20 (important), either 1.3.15 (old design), 2.14 (if you want new UI) from here: https://sourceforge.net/projects/mantisbt/files/mantis-stable/ and unpack them to respective mantis108, mantis120, mantis1220, mantis1315, mantis214 folders
  • unpack to htdocs all those versions
  • move your official 1.0.8 to maintenance mode (rename mantis_offline.php.sample to mantis_offline.php)
  • make a backup (I believe it has been made already) of your database
  • import the backup to your local database
  • launch mantis108
  • put there your imported database name and root credentials, make the setup locally
  • assure yourself you can login with your local import, if so, the initial step was made perfectly. At this moment you spent around 15 minutes.
    IF TROUBLES:
  • download XAMP with version of PHP 4.4, because requirements were MySQL 3.23.2 and higher, PHP 4.0.6 and higher
  • restart list above
    Everything should go fine

Migration:

  • launch URL in your web browser http://localhost/mantis120

  • push your credentials with the same Database name and root

  • login as admin and briefly verify everything is ok

  • launch URL http://localhost/mantis1220 - it's important, because something strange was made with migration before the version and upper.

  • push your credentials

  • login as admin and briefly verify everything is ok

  • launch either http://localhost/mantis1315 or http://localhost/mantis214

  • push your credentials

  • login as admin and briefly verify everything is ok

  • merge your initial config_inc.php in root folder with mantis214/config/config_inc.php

Enojoy.. Since the 1.0.8 you should spend around extra 15 minutes, if you made everything as I said and didn't skip a step.

dregad

dregad

2018-05-16 03:21

developer   ~0059827

@aberaza86, I would ignore @Rost's suggestion in your case. You are already past the potential problems he tried to solve.

What you reported in the the last 2 notes is completely unrelated to the original issue.

  • With regards to your note 0024416:0059803 - the constants are defined in core/constants_inc.php, which is included in MantisBT core (core.php), so your getting these error message probably means that you did not perform your installation as per the indications in the admin guide or changed something afterwards.
  • As for 0024416:0059804, replaced the file "C: \ xampp \ htdocs \ mantisbt-2 \ config_defaults_inc.php" with the one of the previous installation - Don't do that.

As per my earlier suggestion, please try the upgrade with the code from https://github.com/dregad/mantisbt/archive/install-unserialize.zip

atrol

atrol

2018-05-16 03:32

developer   ~0059828

try the upgrade with the code from https://github.com/dregad/mantisbt/archive/install-unserialize.zip

The zip-file does not contain the vendor folder.
@aberaza86 you have to copy it from your 2.14.0 download

aberaza86

aberaza86

2018-05-16 08:54

reporter   ~0059837

I tried to install the update with the code of https://github.com/dregad/mantisbt/archive/install-unserialize.zip. I copied the Vendor folder that I had and this is the message he gave.

Schema step 195: UpdateFunction ( stored_filter_migrate )

Filter id 212 could not be converted because its data is not valid. Fix the problem by manually repairing or deleting the offending mantis_filters_table row as appropriate, then try again.
Error: unserialize(): Error at offset 1063 of 1160 bytes occured because of the string below

a:33:{s:8:"_version";s:2:"v7";s:10:"_view_type";s:8:"advanced";s:8:"per_page";i:400;s:17:"highlight_changed";i:6;s:13:"sticky_issues";s:2:"on";s:4:"sort";s:12:"last_updated";s:3:"dir";s:3:"ASC";s:11:"start_month";i:1;s:9:"start_day";i:1;s:10:"start_year";i:2010;s:9:"end_month";i:1;s:7:"end_day";i:29;s:8:"end_year";i:2010;s:6:"search";s:0:"";s:16:"and_not_assigned";b:0;s:17:"do_filter_by_date";b:0;s:10:"view_state";i:0;s:17:"relationship_type";i:-1;s:16:"relationship_bug";i:0;s:13:"show_category";a:1:{i:0;s:1:"0";}s:13:"show_severity";a:1:{i:0;i:0;}s:11:"show_status";a:1:{i:0;i:0;}s:11:"reporter_id";a:1:{i:0;i:62;}s:10:"handler_id";a:1:{i:0;i:0;}s:15:"show_resolution";a:1:{i:0;i:0;}s:13:"show_priority";a:1:{i:0;i:0;}s:10:"show_build";a:1:{i:0;s:1:"0";}s:12:"show_version";a:1:{i:0;s:1:"0";}s:11:"hide_status";a:1:{i:0;i:-2;}s:16:"fixed_in_version";a:1:{i:0;s:1:"0";}s:12:"user_monitor";a:1:{i:0;i:0;}s:12:"show_profile";a:1:{i:0;i:0;}s:13:"custom_fields";a:8:{i:13;a:1:{i:0;s:1:"0";}i:1;a:1:{i:0;s:1:"0";}i:17;a:1:{i:0;s:1:"0";}i:2;a:1:{i:0;s:8:"Créditos";}i:6;a:1:{i:0;s:1:"0";}i:15;a:1:{i:0;s:1:"0";}i:14;a:1:{i:0;s:1:"0";}i:12;a:1:{i:0;s:1:"0";}}}



error_mantis_7.jpg (68,640 bytes)
error_mantis_7.jpg (68,640 bytes)
atrol

atrol

2018-05-16 09:03

developer   ~0059838

From 0024416:0059769

The first line (status_enum_workflow) is causing the error. Apparently, every time a á is present in the string (e.g. "se necesitan más datos") , the count of characters is off by 1 (e.g. 85 instead of 86 for the first occurence). Not sure what the root cause for that is.

Now there is é in filter string.

@dregad I assume the database is not UTF-8 encoded.

@aberaza86 please run admin/check/index.php and attach the results

aberaza86

aberaza86

2018-05-16 09:15

reporter   ~0059839

I ran admin / check / index.php, these are the results.



error_mantis_8.jpg (171,202 bytes)
error_mantis_8.jpg (171,202 bytes)
aberaza86

aberaza86

2018-05-16 11:36

reporter   ~0059842

After correcting all the lines that contained accent mark. I let myself perform the installation and update of the base.
Anyway I keep giving error when I want to enter an incident.
I also keep having the problem SYSTEM NOTICE: 'Undefined index: name' in 'C: \ xampp \ htdocs \ mantisbt-2 \ core \ columns_api.php' line 361



error_mantis_5-2.jpg (96,649 bytes)
error_mantis_5-2.jpg (96,649 bytes)
atrol

atrol

2018-05-21 16:56

developer   ~0059903

From what I see, you are using PHP 7.2.x on Windows.
There are some known issues related to PHP 7.2 (e.g. using SOAP API), but also users in forum that encountered other issues using PHP 7.2 especially in Windows.

To get rid of the warning, you have to use PHP 7.1 or 7.0.

atrol

atrol

2018-05-21 17:05

developer   ~0059904

After correcting all the lines that contained accent mark. I let myself perform the installation and update of the base.

It seems you did not correct the right way, as an status_enum_workflow causes the warning.
If so, you will not see any longer the warning when using PHP 7.1 or 7.0,, but you will encounter unexpected behavior.

aberaza86

aberaza86

2018-05-25 08:30

reporter   ~0059937

Install the PHP 7.1 version and now I can see the incidents.
But I still have this error when entering the mantisbt.



error_mantis_9.jpg (114,992 bytes)
error_mantis_9.jpg (114,992 bytes)
aberaza86

aberaza86

2018-05-25 08:32

reporter   ~0059938

I leave the file columns_api.php so you can see it



columns_api.php (56,120 bytes)
<?php
# MantisBT - A PHP based bugtracking system

# MantisBT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# MantisBT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Columns API
 *
 * @package CoreAPI
 * @subpackage ColumnsAPI
 * @copyright Copyright 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
 * @copyright Copyright 2002  MantisBT Team - mantisbt-dev@lists.sourceforge.net
 * @link http://www.mantisbt.org
 *
 * @uses access_api.php
 * @uses bug_api.php
 * @uses category_api.php
 * @uses config_api.php
 * @uses constant_inc.php
 * @uses custom_field_api.php
 * @uses date_api.php
 * @uses error_api.php
 * @uses event_api.php
 * @uses file_api.php
 * @uses helper_api.php
 * @uses icon_api.php
 * @uses lang_api.php
 * @uses prepare_api.php
 * @uses print_api.php
 * @uses project_api.php
 * @uses sponsorship_api.php
 * @uses string_api.php
 */

require_api( 'access_api.php' );
require_api( 'bug_api.php' );
require_api( 'category_api.php' );
require_api( 'columns_api.php' );
require_api( 'config_api.php' );
require_api( 'constant_inc.php' );
require_api( 'custom_field_api.php' );
require_api( 'date_api.php' );
require_api( 'error_api.php' );
require_api( 'event_api.php' );
require_api( 'file_api.php' );
require_api( 'helper_api.php' );
require_api( 'icon_api.php' );
require_api( 'lang_api.php' );
require_api( 'prepare_api.php' );
require_api( 'print_api.php' );
require_api( 'project_api.php' );
require_api( 'sponsorship_api.php' );
require_api( 'string_api.php' );

/**
 * Filters an array of columns based on configuration options.  The filtering can remove
 * columns whose features are disabled.
 *
 * @param array $p_columns The columns proposed for display.
 * @return array The columns array after removing the disabled features.
 */
function columns_filter_disabled( array $p_columns ) {
	$t_columns = array();
	$t_enable_profiles = ( config_get( 'enable_profiles' ) == ON );

	foreach ( $p_columns as $t_column ) {
		switch( $t_column ) {
			case 'os':
			case 'os_build':
			case 'platform':
				if( ! $t_enable_profiles ) {
					continue 2;
				}
				break;

			case 'eta':
				if( config_get( 'enable_eta' ) == OFF ) {
					continue 2;
				}
				break;

			case 'projection':
				if( config_get( 'enable_projection' ) == OFF ) {
					continue 2;
				}
				break;

			case 'build':
				if( config_get( 'enable_product_build' ) == OFF ) {
					continue 2;
				}
				break;

			case 'sponsorship_total':
				if( config_get( 'enable_sponsorship' ) == OFF ) {
					continue 2;
				}
				break;

				default:
				# don't filter
				break;
		}
		$t_columns[] = $t_column;
	} # continued 2

	return $t_columns;
}

/**
 * Get a list of standard columns.
 * @param boolean $p_enabled_columns_only Default true, if false returns all columns regardless of configuration settings.
 * @return array of column names
 */
function columns_get_standard( $p_enabled_columns_only = true ) {
	$t_reflection = new ReflectionClass( 'BugData' );
	$t_columns = $t_reflection->getDefaultProperties();

	$t_columns['selection'] = null;
	$t_columns['edit'] = null;
	$t_columns['notes'] = null;
	$t_columns['tags'] = null;

	# Overdue icon column (icons appears if an issue is beyond due_date)
	$t_columns['overdue'] = null;

	# The following fields are used internally and don't make sense as columns
	unset( $t_columns['_stats'] );
	unset( $t_columns['profile_id'] );
	unset( $t_columns['sticky'] );
	unset( $t_columns['loading'] );

	# legacy field
	unset( $t_columns['duplicate_id'] );

	$t_column_names = array_keys( $t_columns );

	if( $p_enabled_columns_only ) {
		$t_column_names = columns_filter_disabled( $t_column_names );
	}

	return $t_column_names;
}

/**
 * Allow plugins to define a set of class-based columns, and register/load
 * them here to be used by columns_api.
 * @return array Mapping of column name to column object
 */
function columns_get_plugin_columns() {
	static $s_column_array = null;

	if( is_null( $s_column_array ) ) {
		$s_column_array = array();

		$t_all_plugin_columns = event_signal( 'EVENT_FILTER_COLUMNS' );
		foreach( $t_all_plugin_columns as $t_plugin => $t_plugin_columns ) {
			foreach( $t_plugin_columns as $t_callback => $t_plugin_column_array ) {
				if( is_array( $t_plugin_column_array ) ) {
					foreach( $t_plugin_column_array as $t_column_item ) {
						if( is_object( $t_column_item ) && $t_column_item instanceof MantisColumn ) {
							$t_column_object = $t_column_item;
						} elseif( class_exists( $t_column_item ) && is_subclass_of( $t_column_item, 'MantisColumn' ) ) {
							$t_column_object = new $t_column_item();
						} else {
							continue;
						}
						$t_column_name = mb_strtolower( $t_plugin . '_' . $t_column_object->column );
						$s_column_array[$t_column_name] = $t_column_object;
					}
				}
			}
		}
	}

	return $s_column_array;
}

/**
 * Get all columns for existing custom_fields
 * @return string Array of column names
 */
function columns_get_custom_fields() {
	static $t_col_names = null;
	if( isset( $t_col_names ) ) {
		return $t_col_names;
	}

	$t_all_cfids = custom_field_get_ids();
	$t_col_names = array();
	foreach( $t_all_cfids as $t_id ) {
		$t_col_names[] = column_get_custom_field_column_name( $t_id );
	}
	return $t_col_names;
}

/**
 * Get all columns active for the current system.
 * This includes standard, custom fields, and plugin columns.
 * Columns for disabled modules are removed from this list, according to system
 * configuration.
 *
 * This function cannot check on current user/project, so it can be used by core
 * in potential unlogged-in scenarios.
 * @return array Array of column names
 */
function columns_get_all_active_columns() {
	$t_columns = array_merge(
			columns_get_standard(),
			array_keys( columns_get_plugin_columns() ),
			columns_get_custom_fields()
			);
	return columns_filter_disabled( $t_columns );
}

/**
 * Returns true if the specified $p_column is a plugin column.
 * @param string $p_column A column name.
 * @return boolean
 */
function column_is_plugin_column( $p_column ) {
	$t_plugin_columns = columns_get_plugin_columns();
	return isset( $t_plugin_columns[$p_column] );
}

/**
 * Get all accessible columns for the current project / current user.
 * @param integer $p_project_id A project identifier.
 * @return array array of columns
 * @access public
 */
function columns_get_all( $p_project_id = null ) {
	$t_columns = columns_get_standard();

	# add plugin columns
	$t_columns = array_merge( $t_columns, array_keys( columns_get_plugin_columns() ) );

	# Add project custom fields to the array.  Only add the ones for which the current user has at least read access.
	if( $p_project_id === null ) {
		$t_project_id = helper_get_current_project();
	} else {
		$t_project_id = $p_project_id;
	}
	# Get custom fields from this project and sub-projects
	$t_projects = user_get_all_accessible_projects( null, $t_project_id );
	$t_related_custom_field_ids = custom_field_get_linked_ids( $t_projects );
	foreach( $t_related_custom_field_ids as $t_id ) {
		$t_cfdef = custom_field_get_definition( $t_id );
		$t_projects_to_check = array_intersect( $t_projects, custom_field_get_project_ids( $t_id ) );
		if( access_has_any_project_level( (int)$t_cfdef['access_level_r'], $t_projects_to_check ) ) {
			$t_columns[] = column_get_custom_field_column_name( $t_id );
		}
	}

	return $t_columns;
}

/**
 * Checks if the specified column is an extended column.  Extended columns are native columns that are
 * associated with the issue but are saved in mantis_bug_text_table.
 * @param string $p_column The column name.
 * @return boolean true for extended; false otherwise.
 * @access public
 */
function column_is_extended( $p_column ) {
	switch( $p_column ) {
		case 'description':
		case 'steps_to_reproduce':
		case 'additional_information':
			return true;
		default:
			return false;
	}
}

/**
 * Checks if the specified column is a custom field column.
 * @param string $p_column The column name.
 * @return boolean True if its a custom field column
 */
function column_is_custom_field( $p_column ) {
	$t_cf_columns = columns_get_custom_fields();
	return in_array( $p_column, $t_cf_columns );
}

/**
 * Checks if the specified column can be sorted
 * @param string $p_column The column name.
 * @return boolean True if the column can be sorted
 */
function column_is_sortable( $p_column ) {

	# custom fields are always sortable
	if( column_is_custom_field( $p_column ) ) {
		return true;
	}

	# plugin fields contains a 'sortable' property
	if( column_is_plugin_column( $p_column ) ) {
		$t_plugin_columns = columns_get_plugin_columns();
		$t_plugin_obj = $t_plugin_columns[$p_column];
		return $t_plugin_obj->sortable;
	}

	#standard fields: define exceptions here
	switch( $p_column ) {
		case 'selection':
		case 'edit':
		case 'bugnotes_count':
		case 'attachment_count':
		case 'tags':
		case 'overdue':
		case 'additional_information':
		case 'description':
		case 'notes':
		case 'steps_to_reproduce':
			return false;
	}

	# after all exceptions, return true as default
	return true;
}

/**
 * Given a column name from the array of columns to be included in a view, this method checks if
 * the column is a custom column and if so returns its name.  Note that for custom fields, then
 * provided names will have the "custom_" prefix, where the returned ones won't have the prefix.
 *
 * @param string $p_column Column name.
 * @return string The custom field column name or null if the specific column is not a custom field or invalid column.
 * @access public
 */
function column_get_custom_field_name( $p_column ) {
	if( strncmp( $p_column, 'custom_', 7 ) === 0 ) {
		return mb_substr( $p_column, 7 );
	}

	return null;
}

/**
 * Returns the name of a column corresponding to a custom field, providing the id as parameter.
 *
 * @param integer $p_cf_id	Custom field id
 * @return string	The column name
 */
function column_get_custom_field_column_name( $p_cf_id ) {
	$t_def = custom_field_get_definition( $p_cf_id );
	if( $t_def ) {
		return 'custom_' . $t_def['name'];
	} else {
		return null;
	}
}

/**
 * Converts a string of comma separate column names to an array.
 *
 * @param string $p_string Comma separate column name (not case sensitive).
 * @return array The array with all column names lower case.
 * @access public
 */
function columns_string_to_array( $p_string ) {
	$t_columns = explode( ',', $p_string );
	$t_count = count( $t_columns );

	for( $i = 0; $i < $t_count; $i++ ) {
		$t_columns[$i] = trim( $t_columns[$i] );
	}

	return $t_columns;
}

/**
 * Gets the localized title for the specified column.  The column can be native or custom.
 * The custom fields must contain the 'custom_' prefix.
 *
 * @param string $p_column The column name.
 * @return string The column localized name.
 * @access public
 */
function column_get_title( $p_column ) {
	$t_custom_field = column_get_custom_field_name( $p_column );
	if( $t_custom_field !== null ) {
		$t_field_id = custom_field_get_id_from_name( $t_custom_field );

		if( $t_field_id === false ) {
			$t_custom_field = '@' . $t_custom_field . '@';
		} else {
			$t_def = custom_field_get_definition( $t_field_id );
			$t_custom_field = lang_get_defaulted( $t_def['name'] );
		}

		return $t_custom_field;
	}

	$t_plugin_columns = columns_get_plugin_columns();
	if( isset( $t_plugin_columns[$p_column] ) ) {
		$t_column_object = $t_plugin_columns[$p_column];
		return $t_column_object->title;
	}

	switch( $p_column ) {
		case 'attachment_count':
			return lang_get( 'attachments' );
		case 'bugnotes_count':
			return '#';
		case 'category_id':
			return lang_get( 'category' );
		case 'edit':
			return '';
		case 'handler_id':
			return lang_get( 'assigned_to' );
		case 'last_updated':
			return lang_get( 'updated' );
		case 'os_build':
			return lang_get( 'os_version' );
		case 'project_id':
			return lang_get( 'email_project' );
		case 'reporter_id':
			return lang_get( 'reporter' );
		case 'selection':
			return '';
		case 'sponsorship_total':
			return sponsorship_get_currency();
		case 'version':
			return lang_get( 'product_version' );
		case 'view_state':
			return lang_get( 'view_status' );
		default:
			return lang_get_defaulted( $p_column );
	}
}

/**
 * Checks an array of columns for duplicate or invalid fields.
 *
 * @param string $p_field_name          The logic name of the array being validated.  Used when triggering errors.
 * @param array  $p_columns_to_validate The array of columns to validate.
 * @param array  $p_columns_all         The list of all valid columns.
 * @return boolean
 * @access public
 */
function columns_ensure_valid( $p_field_name, array $p_columns_to_validate, array $p_columns_all ) {
	$t_columns_all_lower = array_map( 'mb_strtolower', $p_columns_all );

	# Check for invalid fields
	foreach( $p_columns_to_validate as $t_column ) {
		if( !in_array( mb_strtolower( $t_column ), $t_columns_all_lower ) ) {
			error_parameters( $p_field_name, $t_column );
			trigger_error( ERROR_COLUMNS_INVALID, ERROR );
			return false;
		}
	}

	# Check for duplicate fields
	$t_columns_no_duplicates = array();
	foreach( $p_columns_to_validate as $t_column ) {
		$t_column_lower = mb_strtolower( $t_column );
		if( in_array( $t_column, $t_columns_no_duplicates ) ) {
			error_parameters( $p_field_name, $t_column );
			trigger_error( ERROR_COLUMNS_DUPLICATE, ERROR );
		} else {
			$t_columns_no_duplicates[] = $t_column_lower;
		}
	}

	return true;
}

/**
 * Validates an array of column names and removes ones that are not valid.  The validation
 * is not case sensitive.
 *
 * @param array $p_columns     The array of column names to be validated.
 * @param array $p_columns_all The array of all valid column names.
 * @return array The array of valid column names found in $p_columns.
 * @access public
 */
function columns_remove_invalid( array $p_columns, array $p_columns_all ) {
	$t_columns_all_lower = array_values( array_map( 'mb_strtolower', $p_columns_all ) );
	$t_columns = array();

	foreach( $p_columns as $t_column ) {
		if( in_array( mb_strtolower( $t_column ), $t_columns_all_lower ) ) {
			$t_columns[] = $t_column;
		}
	}

	return $t_columns;
}

/**
 * Print table header for selection column
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_selection( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-selection"> &#160; </th>';
}

/**
 * Print table header for edit column
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_edit( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-edit"> &#160; </th>';
}

/**
 * Print table header for column ID
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-id">';
	print_view_bug_sort_link( lang_get( 'id' ), 'id', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'id' );
	echo '</th>';
}

/**
 * Print table header for column project id
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_project_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-project-id">';
	print_view_bug_sort_link( lang_get( 'email_project' ), 'project_id', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'project_id' );
	echo '</th>';
}

/**
 * Print table header for column reporter id
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_reporter_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-reporter">';
	print_view_bug_sort_link( lang_get( 'reporter' ), 'reporter_id', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'reporter_id' );
	echo '</th>';
}

/**
 * Print table header for column handler id
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_handler_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-assigned-to">';
	print_view_bug_sort_link( lang_get( 'assigned_to' ), 'handler_id', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'handler_id' );
	echo '</th>';
}

/**
 * Print table header for column priority
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_priority( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-priority">';
	# Use short label only when displaying icons
	$t_label = lang_get( config_get( 'show_priority_text' ) ? 'priority' : 'priority_abbreviation' );
	print_view_bug_sort_link( $t_label, 'priority', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'priority' );
	echo '</th>';
}

/**
 * Print table header for column reproducibility
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_reproducibility( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-reproducibility">';
	print_view_bug_sort_link( lang_get( 'reproducibility' ), 'reproducibility', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'reproducibility' );
	echo '</th>';
}

/**
 * Print table header for column projection
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_projection( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-projection">';
	print_view_bug_sort_link( lang_get( 'projection' ), 'projection', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'projection' );
	echo '</th>';
}

/**
 * Print table header for column ETA
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_eta( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-eta">';
	print_view_bug_sort_link( lang_get( 'eta' ), 'eta', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'eta' );
	echo '</th>';
}

/**
 * Print table header for column resolution
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_resolution( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-resolution">';
	print_view_bug_sort_link( lang_get( 'resolution' ), 'resolution', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'resolution' );
	echo '</th>';
}

/**
 * Print table header for column fixed in version
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_fixed_in_version( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-fixed-in-version">';
	print_view_bug_sort_link( lang_get( 'fixed_in_version' ), 'fixed_in_version', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'fixed_in_version' );
	echo '</th>';
}

/**
 * Print table header for column tags
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_tags( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-tags">' . lang_get('tags') . '</th>';
}

/**
 * Print table header for column target version
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_target_version( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-target-version">';
	print_view_bug_sort_link( lang_get( 'target_version' ), 'target_version', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'target_version' );
	echo '</th>';
}

/**
 * Print table header for column view state
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_view_state( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-view-state">';
	$t_view_state_text = lang_get( 'view_status' );
	$t_view_state_icon = ' <i class="fa fa-lock" title="' . $t_view_state_text . '"></i>';
	print_view_bug_sort_link( $t_view_state_icon, 'view_state', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'view_state' );
	echo '</th>';
}

/**
 * Print table header for column OS
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_os( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-os">';
	print_view_bug_sort_link( lang_get( 'os' ), 'os', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'os' );
	echo '</th>';
}

/**
 * Print table header for column OS Build
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_os_build( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-os-build">';
	print_view_bug_sort_link( lang_get( 'os_version' ), 'os_build', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'os_build' );
	echo '</th>';
}

/**
 * Print table header for column Build
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_build( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	if( $p_columns_target != COLUMNS_TARGET_CSV_PAGE ) {
		echo '<th class="column-build">';
		print_view_bug_sort_link( lang_get( 'build' ), 'build', $p_sort, $p_dir, $p_columns_target );
		print_sort_icon( $p_dir, $p_sort, 'build' );
		echo '</th>';
	} else {
		echo lang_get( 'build' );
	}
}

/**
 * Print table header for column Platform
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_platform( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-platform">';
	print_view_bug_sort_link( lang_get( 'platform' ), 'platform', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'platform' );
	echo '</th>';
}

/**
 * Print table header for column version
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_version( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-version">';
	print_view_bug_sort_link( lang_get( 'product_version' ), 'version', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'version' );
	echo '</th>';
}

/**
 * Print table header for column date submitted
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_date_submitted( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-date-submitted">';
	print_view_bug_sort_link( lang_get( 'date_submitted' ), 'date_submitted', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'date_submitted' );
	echo '</th>';
}

/**
 * Print table header for column attachment count
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_attachment_count( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_attachment_count_text = lang_get( 'attachment_count' );
	$t_attachment_count_icon = "<i class=\"fa fa-paperclip blue\" title=\"$t_attachment_count_text\" ></i>";
	echo "\t" . '<th class="column-attachments">' . $t_attachment_count_icon . '</th>' . "\n";
}

/**
 * Print table header for column category
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_category_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-category">';
	print_view_bug_sort_link( lang_get( 'category' ), 'category_id', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'category_id' );
	echo '</th>';
}

/**
 * Prints Category column header
 * The actual column is 'category_id', this function is just here for backwards
 * compatibility
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_category( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	trigger_error( ERROR_GENERIC, WARNING );
	print_column_title_category_id( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE );
}

/**
 * Print table header for column sponsorship total
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_sponsorship_total( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo "\t<th class=\"column-sponsorship\">";
	print_view_bug_sort_link( sponsorship_get_currency(), 'sponsorship_total', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'sponsorship_total' );
	echo "</th>\n";
}

/**
 * Print table header for column severity
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_severity( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-severity">';
	print_view_bug_sort_link( lang_get( 'severity' ), 'severity', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'severity' );
	echo '</th>';
}

/**
 * Print table header for column status
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_status( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-status">';
	print_view_bug_sort_link( lang_get( 'status' ), 'status', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'status' );
	echo '</th>';
}

/**
 * Print table header for column last updated
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_last_updated( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-last-modified">';
	print_view_bug_sort_link( lang_get( 'updated' ), 'last_updated', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'last_updated' );
	echo '</th>';
}

/**
 * Print table header for column summary
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_summary( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-summary">';
	print_view_bug_sort_link( lang_get( 'summary' ), 'summary', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'summary' );
	echo '</th>';
}

/**
 * Print table header for column bugnotes count
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_bugnotes_count( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-bugnotes-count"> <i class="fa fa-comments blue"></i> </th>';
}

/**
 * Print table header for column description
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_description( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-description">';
	echo lang_get( 'description' );
	echo '</th>';
}

/**
 * Print table header for notes column.
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_notes( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-notes">';
	echo lang_get( 'bug_notes_title' );
	echo '</th>';
}

/**
 * Print table header for column steps to reproduce
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_steps_to_reproduce( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-steps-to-reproduce">';
	echo lang_get( 'steps_to_reproduce' );
	echo '</th>';
}

/**
 * Print table header for column additional information
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_additional_information( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-additional-information">';
	echo lang_get( 'additional_information' );
	echo '</th>';
}

/**
 * Prints Due Date column header
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_due_date( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-due-date">';
	print_view_bug_sort_link( lang_get( 'due_date' ), 'due_date', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'due_date' );
	echo '</th>';
}

/**
 * Print table header for column overdue
 *
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_overdue( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-overdue">';
	$t_overdue_text = lang_get( 'overdue' );
	$t_overdue_icon = ' <i class="fa fa-times-circle-o" title="' . $t_overdue_text . '"></i>';
	print_view_bug_sort_link( $t_overdue_icon, 'due_date', $p_sort, $p_dir, $p_columns_target );
	print_sort_icon( $p_dir, $p_sort, 'due_date' );
	echo '</th>';
}

/**
 * Print table data for column selection
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_selection( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	global $g_checkboxes_exist;

	echo '<td class="column-selection">';
	if( # check report_bug_threshold for the actions "copy" or "move" into any other project
		access_has_any_project_level( 'report_bug_threshold' ) ||
		# !TODO: check if any other projects actually exist for the bug to be moved to
		access_has_project_level( config_get( 'move_bug_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		# !TODO: factor in $g_auto_set_status_to_assigned == ON
		access_has_project_level( config_get( 'update_bug_assign_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		access_has_project_level( config_get( 'update_bug_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		access_has_project_level( config_get( 'delete_bug_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		# !TODO: check to see if the bug actually has any different selectable workflow states
		access_has_project_level( config_get( 'update_bug_status_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		access_has_project_level( config_get( 'set_bug_sticky_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		access_has_project_level( config_get( 'change_view_status_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		access_has_project_level( config_get( 'add_bugnote_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		access_has_project_level( config_get( 'tag_attach_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ||
		access_has_project_level( config_get( 'roadmap_update_threshold', null, null, $p_bug->project_id ), $p_bug->project_id ) ) {
		$g_checkboxes_exist = true;
		echo '<div class="checkbox no-padding no-margin"><label>';
		printf( '<input type="checkbox" name="bug_arr[]" value="%d" class="ace" />', $p_bug->id );
		echo '<span class="lbl"></span>';
		echo '</label></div>';
	} else {
		echo '&#160;';
	}
	echo '</td>';
}

/**
 * Print column title for a specific custom column.
 *
 * @param string  $p_column         Active column.
 * @param object  $p_column_object  Column object.
 * @param string  $p_sort           Sort.
 * @param string  $p_dir            Direction.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_title_plugin( $p_column, $p_column_object, $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<th class="column-plugin">';
	if( $p_column_object->sortable ) {
		print_view_bug_sort_link( string_display_line( $p_column_object->title ), $p_column, $p_sort, $p_dir, $p_columns_target );
		print_sort_icon( $p_dir, $p_sort, $p_column );
	} else {
		echo string_display_line( $p_column_object->title );
	}
	echo '</th>';
}

/**
 * Print custom column content for a specific bug.
 * @param object  $p_column_object  Column object.
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_plugin( $p_column_object, BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	if( $p_columns_target != COLUMNS_TARGET_CSV_PAGE ) {
		echo '<td class="column-plugin">';
		$p_column_object->display( $p_bug, $p_columns_target );
		echo '</td>';
	} else {
		$p_column_object->display( $p_bug, $p_columns_target );
	}
}

/**
 * Print column content for column edit
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_edit( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {

	echo '<td class="column-edit">';

	if( !bug_is_readonly( $p_bug->id ) && access_has_bug_level( config_get( 'update_bug_threshold' ), $p_bug->id ) ) {
		echo '<a href="' . string_get_bug_update_url( $p_bug->id ) . '">';
		echo '<i class="fa fa-pencil bigger-130 padding-2 grey"';
		echo ' title="' . lang_get( 'update_bug_button' ) . '"></i></a>';
	} else {
		echo '&#160;';
	}

	echo '</td>';
}

/**
 * Print column content for column priority
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_priority( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-priority">';
	if( ON == config_get( 'show_priority_text' ) ) {
		print_formatted_priority_string( $p_bug );
	} else {
		print_status_icon( $p_bug->priority );
	}
	echo '</td>';
}

/**
 * Print column content for column id
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_id( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-id">';
	print_bug_link( $p_bug->id, false );
	echo '</td>';
}

/**
 * Print column content for column sponsorship total
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_sponsorship_total( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo "\t<td class=\"right column-sponsorship\">";

	if( $p_bug->sponsorship_total > 0 ) {
		$t_sponsorship_amount = sponsorship_format_amount( $p_bug->sponsorship_total );
		echo string_no_break( $t_sponsorship_amount );
	}

	echo "</td>\n";
}

/**
 * Print column content for column bugnotes count
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_bugnotes_count( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	global $g_filter;

	# grab the bugnote count
	$t_bugnote_stats = bug_get_bugnote_stats( $p_bug->id );
	if( null !== $t_bugnote_stats ) {
		$t_bugnote_count = $t_bugnote_stats['count'];
		$v_bugnote_updated = $t_bugnote_stats['last_modified'];
	} else {
		$t_bugnote_count = 0;
	}

	echo '<td class="column-bugnotes-count">';
	if( $t_bugnote_count > 0 ) {
		$t_show_in_bold = $v_bugnote_updated > strtotime( '-' . $g_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] . ' hours' );
		if( $t_show_in_bold ) {
			echo '<span class="bold">';
		}
		print_link( string_get_bug_view_url( $p_bug->id ) . '&nbn=' . $t_bugnote_count . '#bugnotes', $t_bugnote_count );
		if( $t_show_in_bold ) {
			echo '</span>';
		}
	} else {
		echo '&#160;';
	}

	echo '</td>';
}

/**
 * Print column content for column attachment count
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_attachment_count( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {

	# Check for attachments
	$t_attachment_count = 0;
	if( file_can_view_bug_attachments( $p_bug->id, null ) ) {
		$t_attachment_count = file_bug_attachment_count( $p_bug->id );
	}

	echo '<td class="column-attachments">';

	if( $t_attachment_count > 0 ) {
		$t_href = string_get_bug_view_url( $p_bug->id ) . '#attachments';
		$t_href_title = sprintf( lang_get( 'view_attachments_for_issue' ), $t_attachment_count, $p_bug->id );
		echo '<a href="' . $t_href . '" title="' . $t_href_title . '">' . $t_attachment_count . '</a>';
	} else {
		echo ' &#160; ';
	}

	echo "</td>\n";
}

/**
 * Print column content for column category id
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_category_id( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	global $t_sort, $t_dir;

	# grab the project name
	$t_project_name = project_get_field( $p_bug->project_id, 'name' );

	echo '<td class="column-category">';
	echo '<div class="align-left">';

	# type project name if viewing 'all projects' or if issue is in a subproject
	if( ON == config_get( 'show_bug_project_links' ) && helper_get_current_project() != $p_bug->project_id ) {
		echo '<span class="small project">[';
		print_view_bug_sort_link( string_display_line( $t_project_name ), 'project_id', $t_sort, $t_dir, $p_columns_target );
		echo ']</span>&#160;&#160;';
	}

	echo string_display_line( category_full_name( $p_bug->category_id, false ) );
	echo '</div>';
	echo '</td>';
}

/**
 * Print column content for column severity
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_severity( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-severity">';
	print_formatted_severity_string( $p_bug );
	echo '</td>';
}

/**
 * Print column content for column eta
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_eta( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-eta">', get_enum_element( 'eta', $p_bug->eta, auth_get_current_user_id(), $p_bug->project_id ), '</td>';
}

/**
 * Print column content for column projection
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_projection( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-projection">', get_enum_element( 'projection', $p_bug->projection, auth_get_current_user_id(), $p_bug->project_id ), '</td>';
}

/**
 * Print column content for column reproducibility
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_reproducibility( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-reproducibility">', get_enum_element( 'reproducibility', $p_bug->reproducibility, auth_get_current_user_id(), $p_bug->project_id ), '</td>';
}

/**
 * Print column content for column resolution
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_resolution( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-resolution">',
		get_enum_element( 'resolution', $p_bug->resolution, auth_get_current_user_id(), $p_bug->project_id ),
		'</td>';
}

/**
 * Print column content for column status
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_status( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_current_user = auth_get_current_user_id();
	# choose color based on status
	$status_label = html_get_status_css_class( $p_bug->status, $t_current_user, $p_bug->project_id );
	echo '<td class="column-status">';
	echo '<div class="align-left">';
	echo '<i class="fa fa-square fa-status-box ' . $status_label . '"></i> ';
	printf( '<span title="%s">%s</span>',
		get_enum_element( 'resolution', $p_bug->resolution, $t_current_user, $p_bug->project_id ),
		get_enum_element( 'status', $p_bug->status, $t_current_user, $p_bug->project_id )
	);

	# print handler user next to status
	if( $p_bug->handler_id > 0
			&& ON == config_get( 'show_assigned_names', null, $t_current_user, $p_bug->project_id )
			&& access_can_see_handler_for_bug( $p_bug ) ) {
		printf( ' (%s)', prepare_user_name( $p_bug->handler_id ) );
	}
	echo '</div></td>';
}

/**
 * Print column content for column handler id
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_handler_id( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-assigned-to">';

	# In case of a specific project, if the current user has no access to the field, then it would have been excluded from the
	# list of columns to view.  In case of ALL_PROJECTS, then we need to check the access per row.
	if( $p_bug->handler_id > 0 && ( helper_get_current_project() != ALL_PROJECTS || access_has_project_level( config_get( 'view_handler_threshold' ), $p_bug->project_id ) ) ) {
		echo prepare_user_name( $p_bug->handler_id );
	}

	echo '</td>';
}

/**
 * Print column content for column reporter id
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_reporter_id( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-reporter">';
	echo prepare_user_name( $p_bug->reporter_id );
	echo '</td>';
}

/**
 * Print column content for column project id
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_project_id( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-project-id">';
	echo string_display_line( project_get_name( $p_bug->project_id ) );
	echo '</td>';
}

/**
 * Print column content for column last updated
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_last_updated( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	global $g_filter;

	$t_last_updated = string_display_line( date( config_get( 'short_date_format' ), $p_bug->last_updated ) );

	echo '<td class="column-last-modified">';
	if( $p_bug->last_updated > strtotime( '-' . $g_filter[FILTER_PROPERTY_HIGHLIGHT_CHANGED] . ' hours' ) ) {
		printf( '<span class="bold">%s</span>', $t_last_updated );
	} else {
		echo $t_last_updated;
	}
	echo '</td>';
}

/**
 * Print column content for column date submitted
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_date_submitted( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_date_submitted = string_display_line( date( config_get( 'short_date_format' ), $p_bug->date_submitted ) );

	echo '<td class="column-date-submitted">', $t_date_submitted, '</td>';
}

/**
 * Print column content for column summary
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_summary( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	if( $p_columns_target == COLUMNS_TARGET_CSV_PAGE ) {
		$t_summary = string_attribute( $p_bug->summary );
	} else {
		$t_summary = string_display_line_links( $p_bug->summary );
	}

	echo '<td class="column-summary">' . $t_summary . '</td>';
}

/**
 * Print column content for column description
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_description( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_description = string_display_links( $p_bug->description );

	echo '<td class="column-description">', $t_description, '</td>';
}

/**
 * Print column content for notes column
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_notes( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_notes = bugnote_get_all_visible_as_string( $p_bug->id, /* user_bugnote_order */ 'DESC', /* user_bugnote_limit */ 0 );

	echo '<td class="column-notes">', string_display_links( $t_notes ), '</td>';
}

/**
 * Print column content for column steps to reproduce
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_steps_to_reproduce( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_steps_to_reproduce = string_display_links( $p_bug->steps_to_reproduce );

	echo '<td class="column-steps-to-reproduce">', $t_steps_to_reproduce, '</td>';
}

/**
 * Print column content for column additional information
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_additional_information( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_additional_information = string_display_links( $p_bug->additional_information );

	echo '<td class="column-additional-information">', $t_additional_information, '</td>';
}

/**
 * Print column content for column target version
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_target_version( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-target-version">';

	# In case of a specific project, if the current user has no access to the field, then it would have been excluded from the
	# list of columns to view.  In case of ALL_PROJECTS, then we need to check the access per row.
	if( helper_get_current_project() != ALL_PROJECTS || access_has_project_level( config_get( 'roadmap_view_threshold' ), $p_bug->project_id ) ) {
		echo string_display_line( $p_bug->target_version );
	}

	echo '</td>';
}

/**
 * Print column content for view state column
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_view_state( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {

	echo '<td class="column-view-state">';

	if( VS_PRIVATE == $p_bug->view_state ) {
		$t_view_state_text = lang_get( 'private' );
		echo ' <i class="fa fa-lock" title="' . $t_view_state_text . '"></i>';
	} else {
		echo '&#160;';
	}

	echo '</td>';
}

/**
 * Print column content for column tags
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_tags( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	echo '<td class="column-tags">';

	if( access_has_bug_level( config_get( 'tag_view_threshold' ), $p_bug->id ) ) {
		echo string_display_line( tag_bug_get_all( $p_bug->id ) );
	}

	echo '</td>';
}

/**
 * Print column content for column due date
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_due_date( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
	$t_overdue = '';

	if( !access_has_bug_level( config_get( 'due_date_view_threshold' ), $p_bug->id ) ||
		date_is_null( $p_bug->due_date )
	) {
		$t_value = '&#160;';
	} else {
		if( bug_is_overdue( $p_bug->id ) ) {
			$t_overdue = ' overdue';
		}
		$t_value = string_display_line( date( config_get( 'short_date_format' ), $p_bug->due_date ) );
	}

	printf( '<td class="column-due-date%s">%s</td>', $t_overdue, $t_value );
}

/**
 * Print column content for column overdue
 *
 * @param BugData $p_bug            BugData object.
 * @param integer $p_columns_target See COLUMNS_TARGET_* in constant_inc.php.
 * @return void
 * @access public
 */
function print_column_overdue( BugData $p_bug, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {

	echo '<td class="column-overdue">';

	if( access_has_bug_level( config_get( 'due_date_view_threshold' ), $p_bug->id ) &&
		!date_is_null( $p_bug->due_date ) &&
		bug_is_overdue( $p_bug->id ) ) {
		$t_overdue_text = lang_get( 'overdue' );
		$t_overdue_text_hover = sprintf( lang_get( 'overdue_since' ), date( config_get( 'short_date_format' ), $p_bug->due_date ) );
		echo '<i class="fa fa-times-circle-o" title="' . string_display_line( $t_overdue_text_hover ) . '"></i>';
	} else {
		echo '&#160;';
	}

	echo '</td>';
}
columns_api.php (56,120 bytes)
atrol

atrol

2018-05-25 13:44

developer   ~0059945

Please attach the output of the following SQL statement to the issue
SELECT * FROM mantis_custom_field_table;

aberaza86

aberaza86

2018-05-25 15:37

reporter   ~0059953

I attach the data



mantis_custom_field_table.csv (10,587 bytes)
atrol

atrol

2018-05-26 06:03

developer   ~0059957

After changing to PHP 7.1 and maybe other changes, are you still not able to run the checks admin/check/index.php ?

aberaza86

aberaza86

2018-05-28 09:43

reporter   ~0059961

After changing to PHP 7.1. I can enter the mantis and see the incidents perfectly. what if I still sat down is the error of the column_api.php

atrol

atrol

2018-05-28 10:02

developer   ~0059962

0024416:0059961 does not answer my question from 0024416:0059957

After changing to PHP 7.1 and maybe other changes, are you still not able to run the checks admin/check/index.php ?

If you are not able to run admin/check/index.php, you can execute the following statements

SELECT schema_name, default_collation_name FROM information_schema.schemata;
The value default_collation_name for the mantis database should be utf8_general_ci

Furthermore execute
SHOW TABLE STATUS;
The value collation for all Mantis database tables should be utf8_general_ci

aberaza86

aberaza86

2018-05-28 10:09

reporter   ~0059963

Checking your MantisBT installation...
Verbosity: Show passed tests | Show verbose error messages
PHP
display_errors php.ini directive is disabled
For security reasons this directive should be disabled on all production and Internet facing servers. WARN
display_startup_errors php.ini directive is disabled
For security reasons this directive should be disabled on all production and Internet facing servers. WARN
Database
mysqli.allow_local_infile php.ini directive is set to 0
mysqli.allow_local_infile should be disabled to prevent remote attackers to access local files (see issue 0023173). WARN
MySQL Lifecycle and Release Support data availability
Release information for MySQL 10.1 series is not available, unable to perform the lifecycle checks. WARN
Database default collation is UTF-8
Database is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bug_file_table is using UTF-8 collation
Table mantis_bug_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bug_history_table is using UTF-8 collation
Table mantis_bug_history_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bug_monitor_table is using UTF-8 collation
Table mantis_bug_monitor_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bug_relationship_table is using UTF-8 collation
Table mantis_bug_relationship_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bug_table is using UTF-8 collation
Table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bug_text_table is using UTF-8 collation
Table mantis_bug_text_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bugnote_table is using UTF-8 collation
Table mantis_bugnote_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_bugnote_text_table is using UTF-8 collation
Table mantis_bugnote_text_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_config_table is using UTF-8 collation
Table mantis_config_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_custom_field_project_table is using UTF-8 collation
Table mantis_custom_field_project_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_custom_field_string_table is using UTF-8 collation
Table mantis_custom_field_string_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_custom_field_table is using UTF-8 collation
Table mantis_custom_field_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_filters_table is using UTF-8 collation
Table mantis_filters_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_news_table is using UTF-8 collation
Table mantis_news_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_project_file_table is using UTF-8 collation
Table mantis_project_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_project_hierarchy_table is using UTF-8 collation
Table mantis_project_hierarchy_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_project_table is using UTF-8 collation
Table mantis_project_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_project_user_list_table is using UTF-8 collation
Table mantis_project_user_list_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_project_version_table is using UTF-8 collation
Table mantis_project_version_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_sponsorship_table is using UTF-8 collation
Table mantis_sponsorship_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_tokens_table is using UTF-8 collation
Table mantis_tokens_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_user_pref_table is using UTF-8 collation
Table mantis_user_pref_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_user_print_pref_table is using UTF-8 collation
Table mantis_user_print_pref_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_user_profile_table is using UTF-8 collation
Table mantis_user_profile_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Table mantis_user_table is using UTF-8 collation
Table mantis_user_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column title of type varchar(250) on table mantis_bug_file_table is using UTF-8 collation
Text column title of type varchar(250) on table mantis_bug_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column description of type varchar(250) on table mantis_bug_file_table is using UTF-8 collation
Text column description of type varchar(250) on table mantis_bug_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column diskfile of type varchar(250) on table mantis_bug_file_table is using UTF-8 collation
Text column diskfile of type varchar(250) on table mantis_bug_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column filename of type varchar(250) on table mantis_bug_file_table is using UTF-8 collation
Text column filename of type varchar(250) on table mantis_bug_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column folder of type varchar(250) on table mantis_bug_file_table is using UTF-8 collation
Text column folder of type varchar(250) on table mantis_bug_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column file_type of type varchar(250) on table mantis_bug_file_table is using UTF-8 collation
Text column file_type of type varchar(250) on table mantis_bug_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column field_name of type varchar(64) on table mantis_bug_history_table is using UTF-8 collation
Text column field_name of type varchar(64) on table mantis_bug_history_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column old_value of type varchar(255) on table mantis_bug_history_table is using UTF-8 collation
Text column old_value of type varchar(255) on table mantis_bug_history_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column new_value of type varchar(255) on table mantis_bug_history_table is using UTF-8 collation
Text column new_value of type varchar(255) on table mantis_bug_history_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column os of type varchar(32) on table mantis_bug_table is using UTF-8 collation
Text column os of type varchar(32) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column os_build of type varchar(32) on table mantis_bug_table is using UTF-8 collation
Text column os_build of type varchar(32) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column platform of type varchar(32) on table mantis_bug_table is using UTF-8 collation
Text column platform of type varchar(32) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column version of type varchar(64) on table mantis_bug_table is using UTF-8 collation
Text column version of type varchar(64) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column fixed_in_version of type varchar(64) on table mantis_bug_table is using UTF-8 collation
Text column fixed_in_version of type varchar(64) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column build of type varchar(32) on table mantis_bug_table is using UTF-8 collation
Text column build of type varchar(32) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column summary of type varchar(128) on table mantis_bug_table is using UTF-8 collation
Text column summary of type varchar(128) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column target_version of type varchar(64) on table mantis_bug_table is using UTF-8 collation
Text column target_version of type varchar(64) on table mantis_bug_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column description of type text on table mantis_bug_text_table is using UTF-8 collation
Text column description of type text on table mantis_bug_text_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column steps_to_reproduce of type text on table mantis_bug_text_table is using UTF-8 collation
Text column steps_to_reproduce of type text on table mantis_bug_text_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column additional_information of type text on table mantis_bug_text_table is using UTF-8 collation
Text column additional_information of type text on table mantis_bug_text_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column note_attr of type varchar(250) on table mantis_bugnote_table is using UTF-8 collation
Text column note_attr of type varchar(250) on table mantis_bugnote_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column note of type text on table mantis_bugnote_text_table is using UTF-8 collation
Text column note of type text on table mantis_bugnote_text_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column config_id of type varchar(64) on table mantis_config_table is using UTF-8 collation
Text column config_id of type varchar(64) on table mantis_config_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column value of type text on table mantis_config_table is using UTF-8 collation
Text column value of type text on table mantis_config_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column value of type varchar(255) on table mantis_custom_field_string_table is using UTF-8 collation
Text column value of type varchar(255) on table mantis_custom_field_string_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column text of type longtext on table mantis_custom_field_string_table is using UTF-8 collation
Text column text of type longtext on table mantis_custom_field_string_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column name of type varchar(64) on table mantis_custom_field_table is using UTF-8 collation
Text column name of type varchar(64) on table mantis_custom_field_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column possible_values of type text on table mantis_custom_field_table is using UTF-8 collation
Text column possible_values of type text on table mantis_custom_field_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column default_value of type varchar(255) on table mantis_custom_field_table is using UTF-8 collation
Text column default_value of type varchar(255) on table mantis_custom_field_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column valid_regexp of type varchar(255) on table mantis_custom_field_table is using UTF-8 collation
Text column valid_regexp of type varchar(255) on table mantis_custom_field_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column name of type varchar(64) on table mantis_filters_table is using UTF-8 collation
Text column name of type varchar(64) on table mantis_filters_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column filter_string of type text on table mantis_filters_table is using UTF-8 collation
Text column filter_string of type text on table mantis_filters_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column headline of type varchar(64) on table mantis_news_table is using UTF-8 collation
Text column headline of type varchar(64) on table mantis_news_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column body of type text on table mantis_news_table is using UTF-8 collation
Text column body of type text on table mantis_news_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column title of type varchar(250) on table mantis_project_file_table is using UTF-8 collation
Text column title of type varchar(250) on table mantis_project_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column description of type varchar(250) on table mantis_project_file_table is using UTF-8 collation
Text column description of type varchar(250) on table mantis_project_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column diskfile of type varchar(250) on table mantis_project_file_table is using UTF-8 collation
Text column diskfile of type varchar(250) on table mantis_project_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column filename of type varchar(250) on table mantis_project_file_table is using UTF-8 collation
Text column filename of type varchar(250) on table mantis_project_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column folder of type varchar(250) on table mantis_project_file_table is using UTF-8 collation
Text column folder of type varchar(250) on table mantis_project_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column file_type of type varchar(250) on table mantis_project_file_table is using UTF-8 collation
Text column file_type of type varchar(250) on table mantis_project_file_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column name of type varchar(128) on table mantis_project_table is using UTF-8 collation
Text column name of type varchar(128) on table mantis_project_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column file_path of type varchar(250) on table mantis_project_table is using UTF-8 collation
Text column file_path of type varchar(250) on table mantis_project_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column description of type text on table mantis_project_table is using UTF-8 collation
Text column description of type text on table mantis_project_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column version of type varchar(64) on table mantis_project_version_table is using UTF-8 collation
Text column version of type varchar(64) on table mantis_project_version_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column description of type text on table mantis_project_version_table is using UTF-8 collation
Text column description of type text on table mantis_project_version_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column logo of type varchar(128) on table mantis_sponsorship_table is using UTF-8 collation
Text column logo of type varchar(128) on table mantis_sponsorship_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column url of type varchar(128) on table mantis_sponsorship_table is using UTF-8 collation
Text column url of type varchar(128) on table mantis_sponsorship_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column value of type text on table mantis_tokens_table is using UTF-8 collation
Text column value of type text on table mantis_tokens_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column bugnote_order of type varchar(4) on table mantis_user_pref_table is using UTF-8 collation
Text column bugnote_order of type varchar(4) on table mantis_user_pref_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column language of type varchar(32) on table mantis_user_pref_table is using UTF-8 collation
Text column language of type varchar(32) on table mantis_user_pref_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column timezone of type varchar(32) on table mantis_user_pref_table is using UTF-8 collation
Text column timezone of type varchar(32) on table mantis_user_pref_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column print_pref of type varchar(64) on table mantis_user_print_pref_table is using UTF-8 collation
Text column print_pref of type varchar(64) on table mantis_user_print_pref_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column platform of type varchar(32) on table mantis_user_profile_table is using UTF-8 collation
Text column platform of type varchar(32) on table mantis_user_profile_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column os of type varchar(32) on table mantis_user_profile_table is using UTF-8 collation
Text column os of type varchar(32) on table mantis_user_profile_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column os_build of type varchar(32) on table mantis_user_profile_table is using UTF-8 collation
Text column os_build of type varchar(32) on table mantis_user_profile_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column description of type text on table mantis_user_profile_table is using UTF-8 collation
Text column description of type text on table mantis_user_profile_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column username of type varchar(32) on table mantis_user_table is using UTF-8 collation
Text column username of type varchar(32) on table mantis_user_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column realname of type varchar(64) on table mantis_user_table is using UTF-8 collation
Text column realname of type varchar(64) on table mantis_user_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column email of type varchar(64) on table mantis_user_table is using UTF-8 collation
Text column email of type varchar(64) on table mantis_user_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column password of type varchar(32) on table mantis_user_table is using UTF-8 collation
Text column password of type varchar(32) on table mantis_user_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Text column cookie_string of type varchar(64) on table mantis_user_table is using UTF-8 collation
Text column cookie_string of type varchar(64) on table mantis_user_table is using latin1_swedish_ci collation where UTF-8 collation is required. FAIL
Some tests failed. Please review and correct these failed tests before using MantisBT.
For security reasons, you should delete (or at least restrict access to) the admin directory. Refer to the MantisBT Admin Guide for further details.

atrol

atrol

2018-05-28 10:24

developer   ~0059964

So I was right when writing at 0024416:0059838

I assume the database is not UTF-8 encoded

I am not complete sure, but I assume this is causing the former upgrade issues and maybe also the columns_api.php issue.

You can try to change the encoding in your current upgrades database, but the clean solution would be to start with your old database, convert it to utf-8 and run the upgrade script (that might even run without producing errors).

In case you don't know how to convert, this might help https://stackoverflow.com/questions/8906813/how-to-change-the-default-charset-of-a-mysql-table

aberaza86

aberaza86

2018-06-04 10:12

reporter   ~0060012

I converted my previous base to UTF-8 and then ran the installation again.
This is the mistake he gives me now.



error_mantis_10.jpg (41,963 bytes)
error_mantis_10.jpg (41,963 bytes)
dregad

dregad

2018-06-05 03:18

developer   ~0060013

@aberaza86 please use your brain and try to fix problems on your own before coming here crying for help. This is the exact same error you already reported (and solved) in 0024416:0059762.

aberaza86

aberaza86

2018-06-05 09:24

reporter   ~0060014

I know it's the same mistake (and how it's solved), I'm not stupid. I'll post it again to show that by changing the encoding of the base, that error persists. Because the idea is not to have to replace all the letters with tilde.

dregad

dregad

2018-06-20 06:51

developer   ~0060120

Note that the improvement just committed does not actually fix the issue, it just gives the Admin more detailed information to allow them to take proper corrective action.

Kodiak bear

Kodiak bear

2018-07-17 07:27

reporter   ~0060274

Hello,

I also migrated two very old MantisBT: v1.0.1 and v1.1.7. I started with v2.12.0 and I'm at v2.15.0. I encountered the same problem: "Schema step 193: UpdateFunction (check_config_serialization)". At first I deleted all records of type 3 (21312~0057283) and I could pass this step.

But the solution did not satisfy me because I lost too many lines of configuration.

I noticed in the note 21312~0057283 the presence of the accented character "màs". As in Spanish, the French language has accented characters. I therefore deduced that the problem could come from these characters.
When I do a migration and have the error message from step 193, I execute the following queries to change all accented characters:

UPDATE mantis_config_table
SET value = REPLACE (value, 'é', 'e')
WHERE config_id =" notify_flags ";

UPDATE mantis_config_table
SET value = REPLACE (value, 'é', 'e')
WHERE config_id =" status_enum_workflow ";

UPDATE mantis_config_table
SET value = REPLACE (value, 'to', 'a')
WHERE config_id =" status_enum_workflow ";

UPDATE mantis_config_table
SET value = REPLACE (value, 'ô', 'o')
WHERE config_id =" status_enum_workflow ";

In this way I do not lose any line.

I tried to change the character set of tables in utf8_general_ci, before migrating and when I had the error message, with ALTER TABLE table_name CONVERT TO CHARACTER SET utf8; but I still had the same problem.

I do not have an error at step 194.

When I continue the installation I have an error in step 195 "Schema step 195: UpdateFunction (stored_filter_migrate)"
I execute queries:

UPDATE mantis_filters_table
SET filter_string = REPLACE (filter_string, 'é', 'e');

UPDATE mantis_filters_table
SET filter_string = REPLACE (filter_string, 'to', 'a');

UPDATE mantis_filters_table
SET filter_string = REPLACE (filter_string, 'ô', 'o');

And I have no problem, the migration ends properly.

I'm sorry but three months ago (for my setup and my data) I had solved my problem. Unfortunately my migration project really takes a lot of time and I did not have an account to communicate my solution.
I hope that the information will confirm that the problem is due to accentuated accents.
As soon as I can, I will try to redo a migration with modified files error_api.php,
install_helper_functions_api.php and utility_api.php. I'll get you back as soon as possible.
I think bug 21312 can be solved.

My configuration :

  • MantisBT v2.15.0
  • PHP v7.2.3
  • Centos v7.4
  • Maria DB v5.5.56
  • Apache v2.4.6
Kodiak bear

Kodiak bear

2018-07-17 09:07

reporter   ~0060275

Last edited: 2018-07-17 09:08

View 2 revisions

I just tested the migration by modifying the error_api.php, install_helper_functions_api.php and utility_api.php files.
As specified by degrad the problem is not corrected but I get the detailed information.
There is also no regression: if I execute queries to remove accented characters, the migration completes successfully.

The full line of the screenshot for step 193 :
a:9:{i:10;s:38:"30:accepté,85:A disposition,90:clôturé";i:20;s:21:"30:accepté,90:clôturé";i:30;s:34:"20:demande informations,50:Affecté";i:50;s:9:"80:résolu";i:80;s:39:"82:confirmé,50:Affecté,85:A disposition";i:82;s:27:"85:A disposition,30:accepté";i:85;s:25:"90:clôturé,87: non validé";i:87;s:38:"30:accepté,85:A disposition,90:clôturé";i:90;s:13:"10:en attente";}

The full line of the screenshot for step 195 :
v7#a:33:{s:8:"_version";s:2:"v7";s:10:"_view_type";s:6:"simple";s:8:"per_page";i:50;s:17:"highlight_changed";i:6;s:13:"sticky_issues";s:2:"on";s:4:"sort";s:12:"last_updated";s:3:"dir";s:3:"ASC";s:11:"start_month";s:2:"06";s:9:"start_day";i:1;s:10:"start_year";s:4:"2007";s:9:"end_month";s:2:"06";s:7:"end_day";s:2:"12";s:8:"end_year";s:4:"2007";s:6:"search";s:0:"";s:16:"and_not_assigned";b:0;s:17:"do_filter_by_date";b:0;s:10:"view_state";i:0;s:17:"relationship_type";i:-1;s:16:"relationship_bug";i:0;s:13:"show_category";a:1:{i:0;s:25:"DPPT- Reprise des données";}s:13:"show_severity";a:1:{i:0;i:0;}s:11:"show_status";a:1:{i:0;i:90;}s:11:"reporter_id";a:1:{i:0;i:0;}s:10:"handler_id";a:1:{i:0;i:0;}s:15:"show_resolution";a:1:{i:0;i:0;}s:13:"show_priority";a:1:{i:0;i:0;}s:10:"show_build";a:1:{i:0;s:1:"0";}s:12:"show_version";a:1:{i:0;s:1:"0";}s:11:"hide_status";a:1:{i:0;i:90;}s:16:"fixed_in_version";a:1:{i:0;s:1:"0";}s:12:"user_monitor";a:1:{i:0;i:0;}s:12:"show_profile";a:1:{i:0;i:0;}s:13:"custom_fields";a:3:{i:1;a:1:{i:0;s:1:"0";}i:2;a:1:{i:0;s:1:"0";}i:3;a:1:{i:0;s:1:"0";}}}



step_193.JPG (54,622 bytes)
step_193.JPG (54,622 bytes)
step_195.JPG (60,002 bytes)
step_195.JPG (60,002 bytes)

Related Changesets

MantisBT: master 086f3104

2018-06-20 06:39:52

dregad

Details Diff
Upgrade: improve handling of unserialize errors

Merging PR https://github.com/mantisbt/mantisbt/pull/1359

In MantisBT 1.3, the method used to store config, token and filter data
changed from serialize to JSON. Upgrade steps 193, 194 and 195 were
added to convert legacy data to the new format.

This frequently caused the upgrade process to fail when unserialize()
could not interpret the data, but the MantisBT installer just aborted
without providing any useful information to the admin.

This improves the error reporting, clearly identifying the offending
record so that the admin can take appropriate action to fix the problem.

Fixes 0024416, 0021376 (and maybe others too)
Affected Issues
0021376, 0024416
mod - core/error_api.php Diff File
mod - core/install_helper_functions_api.php Diff File
mod - core/utility_api.php Diff File

Issue History

Date Modified Username Field Change
2018-05-09 14:50 aberaza86 New Issue
2018-05-09 14:50 aberaza86 Issue generated from: 0024415
2018-05-10 13:17 atrol Relationship added has duplicate 0024419
2018-05-10 13:18 atrol Relationship added related to 0021312
2018-05-10 13:22 atrol Status new => feedback
2018-05-10 13:22 atrol Note Added: 0059758
2018-05-10 13:38 aberaza86 File Added: Error_mantis.xlsx
2018-05-10 13:38 aberaza86 Note Added: 0059759
2018-05-10 13:38 aberaza86 Status feedback => new
2018-05-10 13:59 atrol Status new => feedback
2018-05-10 13:59 atrol Note Added: 0059761
2018-05-10 15:07 aberaza86 File Added: error_mantis_2.jpg
2018-05-10 15:07 aberaza86 Note Added: 0059762
2018-05-10 15:07 aberaza86 Status feedback => new
2018-05-10 15:14 aberaza86 File Added: error_mantis_4.jpg
2018-05-10 15:14 aberaza86 File Added: error_mantis_5.jpg
2018-05-10 15:14 aberaza86 Note Added: 0059763
2018-05-10 17:08 atrol Status new => feedback
2018-05-10 17:08 atrol Note Added: 0059764
2018-05-11 07:31 aberaza86 File Added: Error_mantis_2.xlsx
2018-05-11 07:31 aberaza86 Note Added: 0059768
2018-05-11 07:31 aberaza86 Status feedback => new
2018-05-11 10:25 dregad Note Added: 0059769
2018-05-11 10:59 aberaza86 File Added: error_mantis_6.jpg
2018-05-11 10:59 aberaza86 Note Added: 0059770
2018-05-14 08:29 aberaza86 Note Added: 0059783
2018-05-14 14:56 aberaza86 Issue cloned: 0024431
2018-05-15 07:27 dregad Note Added: 0059796
2018-05-15 07:27 dregad Status new => feedback
2018-05-15 10:38 aberaza86 Note Added: 0059803
2018-05-15 10:38 aberaza86 Status feedback => new
2018-05-15 10:39 aberaza86 Note Edited: 0059803 View Revisions
2018-05-15 10:43 aberaza86 Note Added: 0059804
2018-05-15 10:47 Rost Note Added: 0059805
2018-05-15 10:48 Rost Note Edited: 0059805 View Revisions
2018-05-15 12:44 Rost Note Edited: 0059805 View Revisions
2018-05-16 03:21 dregad Note Added: 0059827
2018-05-16 03:32 atrol Note Added: 0059828
2018-05-16 03:32 atrol Status new => feedback
2018-05-16 08:54 aberaza86 File Added: error_mantis_7.jpg
2018-05-16 08:54 aberaza86 Note Added: 0059837
2018-05-16 08:54 aberaza86 Status feedback => new
2018-05-16 09:03 atrol Status new => feedback
2018-05-16 09:03 atrol Note Added: 0059838
2018-05-16 09:15 aberaza86 File Added: error_mantis_8.jpg
2018-05-16 09:15 aberaza86 Note Added: 0059839
2018-05-16 09:15 aberaza86 Status feedback => new
2018-05-16 11:36 aberaza86 File Added: error_mantis_5-2.jpg
2018-05-16 11:36 aberaza86 Note Added: 0059842
2018-05-21 16:34 aberaza86 Issue cloned: 0024471
2018-05-21 16:56 atrol Status new => feedback
2018-05-21 16:56 atrol Note Added: 0059903
2018-05-21 17:05 atrol Note Added: 0059904
2018-05-25 08:30 aberaza86 File Added: error_mantis_9.jpg
2018-05-25 08:30 aberaza86 Note Added: 0059937
2018-05-25 08:30 aberaza86 Status feedback => new
2018-05-25 08:32 aberaza86 File Added: columns_api.php
2018-05-25 08:32 aberaza86 Note Added: 0059938
2018-05-25 08:46 aberaza86 Issue cloned: 0024488
2018-05-25 13:44 atrol Status new => feedback
2018-05-25 13:44 atrol Note Added: 0059945
2018-05-25 15:37 aberaza86 File Added: mantis_custom_field_table.csv
2018-05-25 15:37 aberaza86 Note Added: 0059953
2018-05-25 15:37 aberaza86 Status feedback => new
2018-05-26 06:03 atrol Status new => feedback
2018-05-26 06:03 atrol Note Added: 0059957
2018-05-28 09:43 aberaza86 Note Added: 0059961
2018-05-28 09:43 aberaza86 Status feedback => new
2018-05-28 10:02 atrol Status new => feedback
2018-05-28 10:02 atrol Note Added: 0059962
2018-05-28 10:09 aberaza86 Note Added: 0059963
2018-05-28 10:09 aberaza86 Status feedback => new
2018-05-28 10:24 atrol Status new => feedback
2018-05-28 10:24 atrol Note Added: 0059964
2018-06-04 09:10 atrol Relationship added has duplicate 0024488
2018-06-04 10:12 aberaza86 File Added: error_mantis_10.jpg
2018-06-04 10:12 aberaza86 Note Added: 0060012
2018-06-04 10:12 aberaza86 Status feedback => new
2018-06-05 03:18 dregad Note Added: 0060013
2018-06-05 09:24 aberaza86 Note Added: 0060014
2018-06-20 06:46 dregad Changeset attached => MantisBT master 086f3104
2018-06-20 06:46 dregad Assigned To => dregad
2018-06-20 06:46 dregad Status new => resolved
2018-06-20 06:46 dregad Resolution open => fixed
2018-06-20 06:46 dregad Fixed in Version => 2.16.0
2018-06-20 06:51 dregad Target Version => 2.16.0
2018-06-20 06:51 dregad Note Added: 0060120
2018-07-17 07:27 Kodiak bear Note Added: 0060274
2018-07-17 09:07 Kodiak bear File Added: step_193.JPG
2018-07-17 09:07 Kodiak bear File Added: step_195.JPG
2018-07-17 09:07 Kodiak bear Note Added: 0060275
2018-07-17 09:08 Kodiak bear Note Edited: 0060275 View Revisions
2018-07-21 14:26 vboctor Category migration => upgrade
2018-07-30 00:57 vboctor Status resolved => closed
2018-07-30 03:44 dregad Summary need help to migrate the Mantis 1.0.8 that my current company has to the latest version of 2.14.0. => Improve handling of unserialize errors when upgrading