Merge branch '417-installer-improvements' into '3-2-0'

New Installer

See merge request mike-koch/Mods-for-HESK!73
master
Mike Koch 7 years ago
commit 59fa5c2698

@ -75,6 +75,7 @@ package:
script:
- apt-get update
- apt-get install zip unzip
- cd api
- composer install --no-dev
- cd ../ci
- bash build_zip.sh

@ -22,6 +22,5 @@ require_once(__DIR__ . '/../inc/custom_fields.inc.php');
// Load the ApplicationContext
$builder = new \DI\ContainerBuilder();
$builder->setDefinitionCache(new \Doctrine\Common\Cache\ArrayCache());
$applicationContext = $builder->build();

@ -1,7 +1,7 @@
{
"name": "mike-koch/Mods-for-HESK",
"description": "New UI and features for HESK, a free helpdesk solution",
"minimum-stability": "dev",
"minimum-stability": "stable",
"license": "MIT",
"authors": [
{
@ -19,6 +19,7 @@
"php-http/message": "^1.5",
"php-http/curl-client": "^1.7",
"guzzlehttp/psr7": "^1.3",
"mike-koch/php-di": "4.4.11"
"mike-koch/php-di": "4.4.11",
"doctrine/annotations": "1.2"
}
}

392
api/composer.lock generated

File diff suppressed because it is too large Load Diff

@ -178,6 +178,11 @@ button.dropdown-submit {
min-width: 350px;
}
.installer-login-box {
width: 50%;
min-width: 350px;
}
.login-box-container {
position: relative;
}

@ -0,0 +1,12 @@
<?php
define('IN_SCRIPT', 1);
define('HESK_PATH', '../../');
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
require(HESK_PATH . 'install/migrations/core.php');
hesk_load_database_functions();
$allMigrations = getAllMigrations();
end($allMigrations);
print json_encode(array("lastMigrationNumber" => key($allMigrations)));

@ -0,0 +1,31 @@
<?php
define('IN_SCRIPT', 1);
define('HESK_PATH', '../../');
require(HESK_PATH . 'hesk_settings.inc.php');
require(HESK_PATH . 'inc/common.inc.php');
hesk_load_database_functions();
require(HESK_PATH . 'install/migrations/core.php');
$allMigrations = getAllMigrations();
$json = file_get_contents('php://input');
$request = json_decode($json, true);
/* @var $migration AbstractMigration */
$migration = $allMigrations[$request['migrationNumber']];
hesk_dbConnect();
if ($request['direction'] === 'up') {
$migration->up($hesk_settings);
} elseif ($request['direction'] === 'down') {
$migration->down($hesk_settings);
} else {
output(array("message" => "Invalid direction provided"), 400);
}
function output($data, $response = 200, $header = "Content-Type: application/json") {
http_response_code($response);
header($header);
print json_encode($data);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

@ -0,0 +1,290 @@
<?php
define('IN_SCRIPT', 1);
define('HESK_PATH', '../');
require(HESK_PATH . 'install/install_functions.inc.php');
require(HESK_PATH . 'hesk_settings.inc.php');
hesk_dbConnect();
?>
<html>
<head>
<title>Mods For HESK Database Validation</title>
<link href="<?php echo HESK_PATH; ?>hesk_style.css?<?php echo HESK_NEW_VERSION; ?>" type="text/css" rel="stylesheet"/>
<link href="<?php echo HESK_PATH; ?>css/bootstrap.css?v=<?php echo $hesk_settings['hesk_version']; ?>"
type="text/css" rel="stylesheet"/>
<link href="<?php echo HESK_PATH; ?>css/bootstrap-theme.css?v=<?php echo $hesk_settings['hesk_version']; ?>"
type="text/css" rel="stylesheet"/>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<link href="<?php echo HESK_PATH; ?>css/hesk_newStyle.css" type="text/css" rel="stylesheet"/>
<script src="<?php echo HESK_PATH; ?>js/jquery-1.10.2.min.js"></script>
<script language="Javascript" type="text/javascript" src="<?php echo HESK_PATH; ?>js/bootstrap.min.js"></script>
<script language="Javascript" type="text/javascript"
src="<?php echo HESK_PATH; ?>js/modsForHesk-javascript.js"></script>
</head>
<body>
<div class="headersm">Mods for HESK Database Validation</div>
<div class="container">
<div class="page-header">
<h1>Mods for HESK Database Validation</h1>
<p>The database validation tool will check your database setup to ensure that everything is set up correctly.
As of this time, the database validator assumes you are running the latest version of Mods for HESK (<?php echo MODS_FOR_HESK_NEW_VERSION; ?>)</p>
</div>
<div class="panel panel-success" id="all-good" style="display: none">
<div class="panel-heading">
<h4>Success</h4>
</div>
<div class="panel-body text-center">
<i class="fa fa-check-circle fa-4x" style="color: green"></i><br>
<h4>Your database is valid</h4>
</div>
</div>
<div class="panel panel-danger" id="not-good" style="display: none">
<div class="panel-heading">
<h4>Failure</h4>
</div>
<div class="panel-body text-center">
<i class="fa fa-times-circle fa-4x" style="color: red"></i><br>
<h4>One or more columns / tables are not properly configured in your database. Please open a topic at the
<a href="https://developers.phpjunkyard.com/viewforum.php?f=19" target="_blank">PHP Junkyard Forums</a> with this information for assistance.</h4>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Results</h4>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Database Change</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php
$all_good = true;
output_header_row('1.0.0 - 1.3.x');
$all_good = run_table_check('statuses');
$all_good &= run_column_check('statuses', 'ID');
$all_good &= run_column_check('statuses', 'TextColor');
$all_good &= run_column_check('statuses', 'IsNewTicketStatus');
$all_good &= run_column_check('statuses', 'IsClosed');
$all_good &= run_column_check('statuses', 'IsClosedByClient');
$all_good &= run_column_check('statuses', 'IsCustomerReplyStatus');
$all_good &= run_column_check('statuses', 'IsStaffClosedOption');
$all_good &= run_column_check('statuses', 'IsStaffReopenedStatus');
$all_good &= run_column_check('statuses', 'IsDefaultStaffReplyStatus');
$all_good &= run_column_check('statuses', 'LockedTicketStatus');
output_header_row('1.5.0');
$all_good &= run_column_check('users', 'active');
output_header_row('1.6.0');
$all_good &= run_column_check('users', 'notify_note_unassigned');
$all_good &= run_table_check('settings');
output_header_row('1.7.0');
$all_good &= run_table_check('verified_emails');
$all_good &= run_table_check('pending_verification_emails');
$all_good &= run_table_check('stage_tickets');
output_header_row('2.2.0');
$all_good &= run_column_check('statuses', 'IsAutocloseOption');
$all_good &= run_column_check('statuses', 'Closable');
output_header_row('2.3.0');
$all_good &= run_column_check('service_messages', 'icon');
$all_good &= run_column_check('statuses', 'Key');
$all_good &= run_column_check('tickets', 'latitude');
$all_good &= run_column_check('tickets', 'longitude');
$all_good &= run_column_check('stage_tickets', 'latitude');
$all_good &= run_column_check('stage_tickets', 'longitude');
$all_good &= run_column_check('categories', 'manager');
$all_good &= run_column_check('users', 'permission_template');
$all_good &= run_table_check('permission_templates');
$all_good &= run_column_check('permission_templates', 'id');
$all_good &= run_column_check('permission_templates', 'name');
$all_good &= run_column_check('permission_templates', 'heskprivileges');
$all_good &= run_column_check('permission_templates', 'categories');
output_header_row('2.4.0');
$all_good &= run_table_check('quick_help_sections');
$all_good &= run_column_check('quick_help_sections', 'id');
$all_good &= run_column_check('quick_help_sections', 'location');
$all_good &= run_column_check('quick_help_sections', 'show');
$all_good &= run_table_check('text_to_status_xref');
$all_good &= run_column_check('text_to_status_xref', 'id');
$all_good &= run_column_check('text_to_status_xref', 'language');
$all_good &= run_column_check('text_to_status_xref', 'text');
$all_good &= run_column_check('text_to_status_xref', 'status_id');
$all_good &= run_column_check('statuses', 'sort');
$all_good &= run_column_check('attachments', 'download_count');
$all_good &= run_column_check('kb_attachments', 'download_count');
$all_good &= run_column_check('tickets', 'html');
$all_good &= run_column_check('stage_tickets', 'html');
$all_good &= run_column_check('replies', 'html');
output_header_row('2.5.0');
$all_good &= run_column_check('tickets', 'user_agent');
$all_good &= run_column_check('tickets', 'screen_resolution_width');
$all_good &= run_column_check('tickets', 'screen_resolution_height');
$all_good &= run_column_check('stage_tickets', 'user_agent');
$all_good &= run_column_check('stage_tickets', 'screen_resolution_width');
$all_good &= run_column_check('stage_tickets', 'screen_resolution_height');
output_header_row('2.6.0');
$all_good &= run_table_check('logging');
$all_good &= run_column_check('logging', 'id');
$all_good &= run_column_check('logging', 'username');
$all_good &= run_column_check('logging', 'message');
$all_good &= run_column_check('logging', 'severity');
$all_good &= run_column_check('logging', 'location');
$all_good &= run_column_check('logging', 'timestamp');
$all_good &= run_table_check('user_api_tokens');
$all_good &= run_column_check('user_api_tokens', 'id');
$all_good &= run_column_check('user_api_tokens', 'user_id');
$all_good &= run_column_check('user_api_tokens', 'token');
$all_good &= run_table_check('temp_attachment');
$all_good &= run_column_check('temp_attachment', 'id');
$all_good &= run_column_check('temp_attachment', 'file_name');
$all_good &= run_column_check('temp_attachment', 'saved_name');
$all_good &= run_column_check('temp_attachment', 'size');
$all_good &= run_column_check('temp_attachment', 'type');
$all_good &= run_column_check('temp_attachment', 'date_uploaded');
$all_good &= run_table_check('calendar_event');
$all_good &= run_column_check('calendar_event', 'id');
$all_good &= run_column_check('calendar_event', 'start');
$all_good &= run_column_check('calendar_event', 'end');
$all_good &= run_column_check('calendar_event', 'all_day');
$all_good &= run_column_check('calendar_event', 'name');
$all_good &= run_column_check('calendar_event', 'location');
$all_good &= run_column_check('calendar_event', 'comments');
$all_good &= run_column_check('calendar_event', 'category');
$all_good &= run_table_check('calendar_event_reminder');
$all_good &= run_column_check('calendar_event_reminder', 'id');
$all_good &= run_column_check('calendar_event_reminder', 'user_id');
$all_good &= run_column_check('calendar_event_reminder', 'event_id');
$all_good &= run_column_check('calendar_event_reminder', 'amount');
$all_good &= run_column_check('calendar_event_reminder', 'unit');
$all_good &= run_column_check('calendar_event_reminder', 'email_sent');
$all_good &= run_column_check('tickets', 'due_date');
$all_good &= run_column_check('tickets', 'overdue_email_sent');
$all_good &= run_column_check('categories', 'usage');
$all_good &= run_column_check('users', 'notify_overdue_unassigned');
$all_good &= run_column_check('users', 'default_calendar_view');
output_header_row('2.6.2');
$all_good &= run_column_check('stage_tickets', 'due_date');
$all_good &= run_column_check('stage_tickets', 'overdue_email_sent');
output_header_row('3.1.0');
$all_good &= run_column_check('categories', 'background_color');
$all_good &= run_column_check('categories', 'foreground_color');
$all_good &= run_column_check('categories', 'display_border_outline');
$all_good &= run_column_check('logging', 'stack_trace');
$all_good &= run_table_check('custom_nav_element');
$all_good &= run_column_check('custom_nav_element', 'id');
$all_good &= run_column_check('custom_nav_element', 'image_url');
$all_good &= run_column_check('custom_nav_element', 'font_icon');
$all_good &= run_column_check('custom_nav_element', 'place');
$all_good &= run_column_check('custom_nav_element', 'url');
$all_good &= run_column_check('custom_nav_element', 'sort');
$all_good &= run_table_check('custom_nav_element_to_text');
$all_good &= run_column_check('custom_nav_element_to_text', 'id');
$all_good &= run_column_check('custom_nav_element_to_text', 'nav_element_id');
$all_good &= run_column_check('custom_nav_element_to_text', 'language');
$all_good &= run_column_check('custom_nav_element_to_text', 'text');
$all_good &= run_column_check('custom_nav_element_to_text', 'subtext');
$all_good &= run_setting_check('admin_navbar_background');
$all_good &= run_setting_check('admin_navbar_background_hover');
$all_good &= run_setting_check('admin_navbar_text');
$all_good &= run_setting_check('admin_navbar_text_hover');
$all_good &= run_setting_check('admin_navbar_brand_background');
$all_good &= run_setting_check('admin_navbar_brand_background_hover');
$all_good &= run_setting_check('admin_navbar_brand_text');
$all_good &= run_setting_check('admin_navbar_brand_text_hover');
$all_good &= run_setting_check('admin_sidebar_background');
$all_good &= run_setting_check('admin_sidebar_background_hover');
$all_good &= run_setting_check('admin_sidebar_text');
$all_good &= run_setting_check('admin_sidebar_text_hover');
$all_good &= run_setting_check('admin_sidebar_font_weight');
$all_good &= run_setting_check('admin_sidebar_header_background');
$all_good &= run_setting_check('admin_sidebar_header_text');
output_header_row('3.2.0');
$all_good &= run_table_check('audit_trail');
$all_good &= run_table_check('audit_trail_to_replacement_values');
$all_good &= run_column_check('categories', 'mfh_description');
$all_good &= run_column_check('custom_fields', 'mfh_description');
$all_good &= run_setting_check('migrationNumber');
if ($all_good) {
echo "<script>$('#all-good').show()</script>";
} else {
echo "<script>$('#not-good').show()</script>";
}
?>
</tbody>
</table>
</div>
</div>
</body>
</html>
<?php
function run_setting_check($setting_name) {
global $hesk_settings;
$res = run_check("SELECT 1 FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` WHERE `Key` = '{$setting_name}'");
$all_good = hesk_dbNumRows($res) > 0;
output_result('<b>Setting Exists</b>: ' . $setting_name, $all_good);
return $all_good !== false;
}
function run_table_check($table_name) {
return run_column_check($table_name, '1');
}
function run_column_check($table_name, $column_name) {
global $hesk_settings;
if ($column_name == '1') {
$all_good = run_check('SELECT ' . $column_name . ' FROM `' . $hesk_settings['db_pfix'] . $table_name . '` LIMIT 1');
output_result('<b>Table Exists</b>: ' . $table_name,
$all_good);
} else {
$all_good = run_check('SELECT `' . $column_name . '` FROM `' . $hesk_settings['db_pfix'] . $table_name . '` LIMIT 1');
output_result('<b>Column Exists</b>: ' . $table_name . '.' . $column_name,
$all_good);
}
return $all_good !== false;
}
function run_check($sql) {
global $hesk_last_query;
global $hesk_db_link;
if (function_exists('mysqli_connect')) {
if (!$hesk_db_link && !hesk_dbConnect()) {
return false;
}
$hesk_last_query = $sql;
return @mysqli_query($hesk_db_link, $sql);
} else {
if (!$hesk_db_link && !hesk_dbConnect()) {
return false;
}
$hesk_last_query = $sql;
return $res = @mysql_query($sql, $hesk_db_link);
}
}
function output_result($change_title, $success) {
$css_color = 'success';
$text = '<span data-toggle="tooltip" title="This looks good!"><i class="fa fa-check-circle"></i> Success</span>';
if (!$success) {
$css_color = 'danger';
$text = '<span data-toggle="tooltip" title="Oh no! Something isn\'t right."><i class="fa fa-times-circle"></i> Failure</span>';
}
$formatted_text = sprintf('<tr class="'.$css_color.'"><td>%s</td><td style="color: %s">%s</td></tr>', $change_title, $css_color, $text);
echo $formatted_text;
}
function output_header_row($text) {
echo '<tr><td colspan="2" style="font-size: 1.2em"><i class="fa fa-chevron-right"></i> ' . $text . '</td></tr>';
}

@ -1,10 +1,204 @@
<?php
define('IN_SCRIPT', 1);
define('HESK_PATH', '../');
require(HESK_PATH . 'install/install_functions.inc.php');
require(HESK_PATH . 'hesk_settings.inc.php');
hesk_dbConnect();
/*
We have four possible installation scenarios:
1. Fresh install - the user has never installed Mods for HESK before. Simply start at migration #0.
2. Installed a really old version - we don't have a previous version to start from.
3. Installed a recent version, but before migrations began - just pull the version # and use the dictionary below.
4. Migration number present in the settings table. Take that number and run with it.
*/
$tableSql = hesk_dbQuery("SHOW TABLES LIKE '" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings'");
$startingMigrationNumber = 1;
if (hesk_dbNumRows($tableSql) > 0) {
// They have installed at LEAST to version 1.6.0. Just pull the version number OR migration number
$migrationNumberSql = hesk_dbQuery("SELECT `Value` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` WHERE `Key` = 'migrationNumber'");
if ($migrationRow = hesk_dbFetchAssoc($migrationNumberSql)) {
$startingMigrationNumber = intval($migrationRow['Value']) + 1;
} else {
$versionSql = hesk_dbQuery("SELECT `Value` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` WHERE `Key` = 'modsForHeskVersion'");
$versionRow = hesk_dbFetchAssoc($versionSql);
$migration_map = array(
// Pre-1.4.0 to 1.5.0 did not have a settings table
'1.6.0' => 22, '1.6.1' => 23, '1.7.0' => 27, '2.0.0' => 37, '2.0.1' => 38, '2.1.0' => 39, '2.1.1' => 42,
'2.2.0' => 47, '2.2.1' => 48, '2.3.0' => 68, '2.3.1' => 69, '2.3.2' => 70, '2.4.0' => 86, '2.4.1' => 87,
'2.4.2' => 88, '2.5.0' => 98, '2.5.1' => 99, '2.5.2' => 100, '2.5.3' => 101, '2.5.4' => 102, '2.5.5' => 103,
'2.6.0' => 121, '2.6.1' => 122, '2.6.2' => 125, '2.6.3' => 126, '2.6.4' => 127, '3.0.0' => 132, '3.0.1' => 133,
'3.0.2' => 135, '3.0.3' => 136, '3.0.4' => 137, '3.0.5' => 138, '3.0.6' => 139, '3.0.7' => 140, '3.1.0' => 153,
'3.1.1' => 154
);
$startingMigrationNumber = $migration_map[$versionRow['Value']];
}
} else {
// migration # => sql for checking
$versionChecks = array(
// 1.5.0 -> users.active
14 => "SHOW COLUMNS FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` LIKE 'active'",
// 1.4.1 -> denied_emails
11 => "SHOW TABLES LIKE '" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_emails'",
// 1.4.0 -> denied ips
9 => "SHOW TABLES LIKE '" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_ips'",
// Pre-1.4.0 but still something -> statuses
7 => "SHOW TABLES LIKE '" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses'"
);
foreach ($versionChecks as $migrationNumber => $sql) {
$rs = hesk_dbQuery($sql);
if (hesk_dbNumRows($rs) > 0) {
$startingMigrationNumber = $migrationNumber;
break;
}
}
}
$installMismatch = false;
if (HESK_NEW_VERSION != $hesk_settings['hesk_version']) {
$installMismatch = true;
}
?>
<html>
<head>
<title>Install | Redirecting...</title>
</head>
<body>
<script>
window.location.replace("mods-for-hesk/modsForHesk.php");
</script>
</body>
</html>
<head>
<title>Mods for HESK <?php echo MODS_FOR_HESK_NEW_VERSION; ?> Install / Upgrade</title>
<link href="<?php echo HESK_PATH; ?>css/bootstrap.css?v=<?php echo $hesk_settings['hesk_version']; ?>"
type="text/css" rel="stylesheet"/>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<link href="<?php echo HESK_PATH; ?>css/AdminLTE.min.css" type="text/css" rel="stylesheet">
<link href="<?php echo HESK_PATH; ?>css/mods-for-hesk-new.css" type="text/css" rel="stylesheet">
<link href="<?php echo HESK_PATH; ?>css/colors.css" type="text/css" rel="stylesheet">
<script src="<?php echo HESK_PATH; ?>js/jquery-1.10.2.min.js"></script>
<script language="Javascript" type="text/javascript" src="<?php echo HESK_PATH; ?>js/bootstrap.min.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo HESK_PATH; ?>install/js/install-script.js"></script>
<style>
body, .login-box-background {
background: url('<?php echo HESK_PATH; ?>install/background.jpg') no-repeat center center fixed;
background-size: cover;
}
</style>
</head>
<body class="fixed" style="min-height: initial;">
<div class="login-box installer-login-box">
<div class="login-box-container">
<div class="login-box-background"></div>
<div class="login-box-body">
<div class="login-logo">
<img src="<?php echo HESK_PATH; ?>install/logo.png" alt="Mods for HESK logo"><br>
<span id="header-text">
<?php if ($installMismatch): ?>
HESK Version Mismatch
<?php else: ?>
Thanks for choosing Mods for HESK.
<?php endif; ?>
</span>
</div>
<?php if ($installMismatch): ?>
<div class="text-center">
<h4>You need to be running HESK 2.7.3 to install Mods for HESK. You currently have HESK <?php echo $hesk_settings['hesk_version']; ?>.</h4>
</div>
<?php else: // BEGIN INSTALL SCREENS ?>
<div data-step="intro" class="login-box-msg">
<h4>Let's get started.</h4>
<p>By continuing, you agree to the terms of the
<a href="http://opensource.org/licenses/MIT" target="_blank">MIT License</a>.</p>
<!--<div class="checkbox">
<label>
<input type="checkbox" name="usage-stats" checked>
Submit anonymous usage statistics (<a href="#" data-toggle="modal" data-target="#usage-modal">What's this?</a>)
</label>
</div>-->
</div>
<div data-step="db-confirm" style="display: none">
<table class="table table-striped" style="background: #fff">
<thead>
<tr>
<th colspan="4">Database Information / File Permissions</th>
</tr>
</thead>
<tbody>
<tr>
<td>Database Host:</td>
<td><?php echo $hesk_settings['db_host']; ?></td>
<td>Database Name:</td>
<td><?php echo $hesk_settings['db_name']; ?></td>
</tr>
<tr>
<td>Database User:</td>
<td><?php echo $hesk_settings['db_user']; ?></td>
<td>Database Password:</td>
<td><?php echo $hesk_settings['db_pass']; ?></td>
</tr>
<tr>
<td>Database Prefix:</td>
<td><?php echo $hesk_settings['db_pfix']; ?></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</div>
<div data-step="install-or-update" class="text-center" style="display: none">
<div id="spinner">
<i class="fa fa-spin fa-spinner fa-4x"></i>
<h4>Initializing...</h4>
</div>
<div id="progress-bar" class="progress" style="display: none">
<div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"
style="width: 0">
</div>
</div>
<br>
<div id="error-block" class="well" style="display: none; font-family: 'Courier New', Courier, monospace">
</div>
<input type="hidden" name="starting-migration-number" value="<?php echo $startingMigrationNumber; ?>">
</div>
<div data-step="complete" class="text-center" style="display: none">
<i class="fa fa-check-circle fa-4x" style="color: green"></i><br><br>
<h4>Make sure to delete your <code>/install</code> folder and then proceed to your
<a href="<?php echo $hesk_settings['hesk_url']; ?>">help desk</a>.</h4>
<br>
</div>
<?php // END INSTALL SCREENS ?>
<div id="buttons">
<div class="btn btn-primary" id="back-button" style="display: none;"><i class="fa fa-chevron-left"></i>&nbsp;&nbsp;&nbsp;Back</div>
<div class="btn btn-default dropdown-toggle" id="tools-button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Tools <span class="caret"></span>
</div>
<ul class="dropdown-menu">
<li><a href="<?php echo HESK_PATH; ?>install/database-validation.php"><i class="fa fa-check-circle"></i> Database Validator</a></li>
<li><a href="<?php echo HESK_PATH; ?>install/uninstall.php"><i class="fa fa-trash"></i> Uninstall Mods for HESK</a></li>
</ul>
<div class="btn btn-primary pull-right" id="next-button">Next&nbsp;&nbsp;&nbsp;<i class="fa fa-chevron-right"></i></div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<p id="hesk-path" style="display: none"><?php echo HESK_PATH; ?></p>
<!--<div class="modal fade" id="usage-modal" tabindex="-1" role="dialog" aria-labelledby="usage-label">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="usage-label">Submitting Anonymous Usage Statistics</h4>
</div>
<div class="modal-body">
<p>This option will send usage statistics and configuration to Mods for HESK developers.</p>
<p>Usage statistics are transmitted using SSL and help us improve future versions of Mods for HESK.</p>
<p>All the data is anonymized and no personal or sensitive information is being transmitted.</p>
<p>If you have questions, please open a <a href="https://developers.phpjunkyard.com/viewforum.php?f=19" target="_blank" rel="noreferrer">forum topic</a>.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>-->
</body>
</html>

@ -16,7 +16,7 @@ if (!defined('IN_SCRIPT')) {die('Invalid attempt');}
// We will be installing this HESK version:
define('HESK_NEW_VERSION','2.7.3');
define('MODS_FOR_HESK_NEW_VERSION','3.1.1');
define('MODS_FOR_HESK_NEW_VERSION','3.2.0');
define('REQUIRE_PHP_VERSION','5.3.0');
define('REQUIRE_MYSQL_VERSION','5.0.7');

@ -0,0 +1,158 @@
var steps = [
{
name: 'intro',
text: 'Thanks for choosing Mods for HESK',
callback: undefined
},
{
name: 'db-confirm',
text: 'Confirm the information below',
callback: undefined
},
{
name: 'install-or-update',
text: 'Updating to the latest version...',
showBack: false,
showNext: false,
callback: installOrUpdate
},
{
name: 'complete',
text: 'Installation / Upgrade Complete',
showBack: false,
callback: undefined
}
];
$(document).ready(function() {
var currentStep = 0;
$('#next-button').click(function() {
goToStep(++currentStep);
});
$('#back-button').click(function() {
goToStep(--currentStep);
});
});
function goToStep(step) {
$('[data-step]').hide();
$('[data-step="' + steps[step].name + '"]').show();
if (step === 0) {
$('#tools-button').show();
$('#back-button').hide();
} else {
$('#tools-button').hide();
$('#back-button').show();
}
if (step === steps.length - 1) {
$('#next-button').hide();
} else {
$('#next-button').show();
}
// Back/Next button overrides
if (steps[step].showBack !== undefined && !steps[step].showBack) {
$('#back-button').hide();
}
if (steps[step].showNext !== undefined && !steps[step].showNext) {
console.log('hiding this');
$('#next-button').hide();
}
$('#header-text').text(steps[step].text);
if (steps[step].callback !== undefined) {
steps[step].callback();
}
}
function installOrUpdate() {
var startingMigrationNumber = parseInt($('input[name="starting-migration-number"]').val());
var heskPath = $('p#hesk-path').text();
$.ajax({
url: heskPath + 'install/ajax/get-migration-ajax.php',
method: 'GET',
success: function(data) {
data = JSON.parse(data);
$('[data-step="install-or-update"] > #spinner').hide();
$('[data-step="install-or-update"] > .progress').show();
// Recursive call that will increment by 1 each time
executeMigration(startingMigrationNumber, startingMigrationNumber, data.lastMigrationNumber, 'up');
}
})
}
function executeMigration(startingMigrationNumber, migrationNumber, latestMigrationNumber, direction) {
var heskPath = $('p#hesk-path').text();
$.ajax({
url: heskPath + 'install/ajax/process-migration.php',
method: 'POST',
data: JSON.stringify({
migrationNumber: migrationNumber,
direction: direction
}),
success: function(data) {
console.log('migrationNumber: ' + migrationNumber);
console.log('latestMigrationNumber: ' + latestMigrationNumber);
console.info('---');
if (migrationNumber === latestMigrationNumber || (migrationNumber === startingMigrationNumber && direction === 'down')) {
updateProgressBar(migrationNumber, latestMigrationNumber, direction === 'down', true);
console.log('%c Success! ', 'color: white; background-color: green; font-size: 2em');
} else {
updateProgressBar(migrationNumber, latestMigrationNumber, false, false);
var newMigrationNumber = direction === 'up' ? migrationNumber + 1 : migrationNumber - 1;
executeMigration(startingMigrationNumber, newMigrationNumber, latestMigrationNumber, direction);
}
},
error: function(response) {
try {
message = JSON.parse(response);
} catch (e) {
message = response.responseText;
}
$errorBlock = $('#error-block');
$errorBlock.html($errorBlock.html() + "<br><br>An error occurred! (Error Code: " + migrationNumber + ")<br>" + message).show();
updateProgressBar(migrationNumber, latestMigrationNumber, true, false);
if (direction === 'up') {
// Revert!
executeMigration(startingMigrationNumber, migrationNumber - 1, latestMigrationNumber, 'down');
} else {
console.error("I even failed to roll back. Yikes! :'(");
}
console.error(message);
}
})
}
function updateProgressBar(migrationNumber, latestMigrationNumber, isError, isFinished) {
var $progressBar = $('#progress-bar');
if (isError === true) {
$progressBar.find('.progress-bar').removeClass('progress-bar-success')
.removeClass('active')
.addClass('progress-bar-danger');
if (isFinished) {
var $errorBlock = $('#error-block');
$errorBlock.html($errorBlock.html() + '<br><br>Successfully reverted database to before the installation/update.');
}
} else {
var percentage = Math.round(migrationNumber / latestMigrationNumber * 100);
$progressBar.find('.progress-bar').css('width', percentage + '%');
}
if (isFinished && !isError) {
goToStep(steps.length - 1);
}
}

@ -0,0 +1,14 @@
function executeMigration(migrationNumber, direction, success, error) {
var heskPath = $('p#hesk-path').text();
$.ajax({
url: heskPath + 'install/ajax/process-migration.php',
method: 'POST',
data: JSON.stringify({
migrationNumber: migrationNumber,
direction: direction
}),
success: success(data),
error: error(data)
})
}

@ -0,0 +1,151 @@
var steps = [
{
name: 'intro',
text: 'Uninstall',
callback: undefined
},
{
name: 'db-confirm',
text: 'Confirm the information below',
callback: undefined
},
{
name: 'uninstall',
text: 'Uninstalling...',
showBack: false,
showNext: false,
callback: uninstall
},
{
name: 'complete',
text: 'Uninstall Process Complete',
showBack: false,
callback: undefined
}
];
$(document).ready(function() {
var currentStep = 0;
$('#next-button').click(function() {
goToStep(++currentStep);
});
$('#back-button').click(function() {
goToStep(--currentStep);
});
});
function goToStep(step) {
$('[data-step]').hide();
$('[data-step="' + steps[step].name + '"]').show();
if (step === 0) {
$('#tools-button').show();
$('#back-button').hide();
} else {
$('#tools-button').hide();
$('#back-button').show();
}
if (step === steps.length - 1) {
$('#next-button').hide();
} else {
$('#next-button').show();
}
// Back/Next button overrides
if (steps[step].showBack !== undefined && !steps[step].showBack) {
$('#back-button').hide();
}
if (steps[step].showNext !== undefined && !steps[step].showNext) {
console.log('hiding this');
$('#next-button').hide();
}
$('#header-text').text(steps[step].text);
if (steps[step].callback !== undefined) {
steps[step].callback();
}
}
function uninstall() {
var startingMigrationNumber = parseInt($('input[name="starting-migration-number"]').val());
var heskPath = $('p#hesk-path').text();
$.ajax({
url: heskPath + 'install/ajax/get-migration-ajax.php',
method: 'GET',
success: function(data) {
data = JSON.parse(data);
$('[data-step="uninstall"] > #spinner').hide();
$('[data-step="uninstall"] > .progress').show();
// Recursive call that will increment by 1 each time
executeMigration(startingMigrationNumber, startingMigrationNumber, 1, 'down');
}
})
}
function executeMigration(startingMigrationNumber, migrationNumber, latestMigrationNumber, direction) {
var heskPath = $('p#hesk-path').text();
$.ajax({
url: heskPath + 'install/ajax/process-migration.php',
method: 'POST',
data: JSON.stringify({
migrationNumber: migrationNumber,
direction: direction
}),
success: function(data) {
console.log('migrationNumber: ' + migrationNumber);
console.log('latestMigrationNumber: ' + latestMigrationNumber);
console.info('---');
if (migrationNumber === latestMigrationNumber) {
updateProgressBar(startingMigrationNumber, migrationNumber, false, true);
console.log('%c Success! ', 'color: white; background-color: green; font-size: 2em');
} else {
updateProgressBar(startingMigrationNumber, migrationNumber, false, false);
var newMigrationNumber = direction === 'up' ? migrationNumber + 1 : migrationNumber - 1;
executeMigration(startingMigrationNumber, newMigrationNumber, latestMigrationNumber, direction);
}
},
error: function(response) {
try {
message = JSON.parse(response);
} catch (e) {
message = response.responseText;
}
$errorBlock = $('#error-block');
$errorBlock.html($errorBlock.html() + "<br><br>An error occurred! (Error Code: " + migrationNumber + ")<br>" + message).show();
updateProgressBar(startingMigrationNumber, migrationNumber, true, false);
console.error(message);
}
})
}
function updateProgressBar(startingMigrationNumber, migrationNumber, isError, isFinished) {
var $progressBar = $('#progress-bar');
if (isError === true) {
$progressBar.find('.progress-bar').removeClass('progress-bar-success')
.addClass('progress-bar-danger');
if (isFinished) {
var $errorBlock = $('#error-block');
$errorBlock.html($errorBlock.html() + '<br><br>Successfully reverted database to before uninstalling.');
}
} else {
var percentage = Math.round((startingMigrationNumber - migrationNumber) / startingMigrationNumber * 100);
$progressBar.find('.progress-bar').css('width', percentage + '%');
}
if (isFinished && !isError) {
goToStep(steps.length - 1);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

@ -0,0 +1,47 @@
<?php
abstract class AbstractMigration {
abstract function up($hesk_settings);
abstract function down($hesk_settings);
function executeQuery($sql)
{
global $hesk_last_query;
global $hesk_db_link;
if (function_exists('mysqli_connect')) {
if (!$hesk_db_link && !hesk_dbConnect()) {
return false;
}
$hesk_last_query = $sql;
if ($res = @mysqli_query($hesk_db_link, $sql)) {
return $res;
} else {
http_response_code(500);
print "Could not execute query: $sql. MySQL said: " . mysqli_error($hesk_db_link);
die();
}
} else {
if (!$hesk_db_link && !hesk_dbConnect()) {
return false;
}
$hesk_last_query = $sql;
if ($res = @mysql_query($sql, $hesk_db_link)) {
return $res;
} else {
http_response_code(500);
print "Could not execute query: $sql. MySQL said: " . mysql_error();
die();
}
}
}
function updateVersion($version, $hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` SET `Value` = '{$version}' WHERE `Key` = 'modsForHeskVersion'");
}
}

@ -0,0 +1,27 @@
<?php
abstract class AbstractUpdatableMigration extends AbstractMigration {
private $migrationNumber;
function __construct($migrationNumber) {
$this->migrationNumber = $migrationNumber;
}
function up($hesk_settings) {
$this->innerUp($hesk_settings);
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` SET `Value` = '" . intval($this->migrationNumber) . "'
WHERE `Key` = 'migrationNumber'");
}
abstract function innerUp($hesk_settings);
function down($hesk_settings) {
$this->innerDown($hesk_settings);
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` SET `Value` = '" . (intval($this->migrationNumber) - 1) . "'
WHERE `Key` = 'migrationNumber'");
}
abstract function innerDown($hesk_settings);
}

@ -0,0 +1,19 @@
<?php
class LegacyUpdateMigration extends AbstractMigration {
private $upVersion;
private $downVersion;
public function __construct($upVersion, $downVersion) {
$this->upVersion = $upVersion;
$this->downVersion = $downVersion;
}
function up($hesk_settings) {
$this->updateVersion($this->upVersion, $hesk_settings);
}
function down($hesk_settings) {
$this->updateVersion($this->downVersion, $hesk_settings);
}
}

@ -0,0 +1,16 @@
<?php
namespace Pre140\Statuses;
use AbstractMigration;
class AddIntColumnUpDropTableDown extends AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `status_int` INT NOT NULL DEFAULT 0 AFTER `status`;");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses`");
}
}

@ -0,0 +1,28 @@
<?php
namespace Pre140\Statuses;
class CreateStatusesTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (
`ID` INT NOT NULL,
`ShortNameContentKey` TEXT NOT NULL,
`TicketViewContentKey` TEXT NOT NULL,
`TextColor` TEXT NOT NULL,
`IsNewTicketStatus` INT NOT NULL DEFAULT 0,
`IsClosed` INT NOT NULL DEFAULT 0,
`IsClosedByClient` INT NOT NULL DEFAULT 0,
`IsCustomerReplyStatus` INT NOT NULL DEFAULT 0,
`IsStaffClosedOption` INT NOT NULL DEFAULT 0,
`IsStaffReopenedStatus` INT NOT NULL DEFAULT 0,
`IsDefaultStaffReplyStatus` INT NOT NULL DEFAULT 0,
`LockedTicketStatus` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`ID`))");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `status_int` INT NOT NULL AFTER `status`;");
}
}

@ -0,0 +1,21 @@
<?php
namespace Pre140\Statuses;
use AbstractMigration;
class DropOldStatusColumn extends AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `status`");
}
function down($hesk_settings) {
$ticketsRS = $this->executeQuery("SELECT `id`, `status_int` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets`;");
while ($currentResult = hesk_dbFetchAssoc($ticketsRS)) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status_int` = '" . intval($currentResult['status']) . "' WHERE `id` = " . $currentResult['id']);
}
}
}

@ -0,0 +1,33 @@
<?php
namespace Pre140\Statuses;
class InsertStatusRecords extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (ID, ShortNameContentKey, TicketViewContentKey, TextColor, IsNewTicketStatus, IsClosed, IsClosedByClient, IsCustomerReplyStatus,
IsStaffClosedOption, IsStaffReopenedStatus, IsDefaultStaffReplyStatus, LockedTicketStatus)
VALUES (0, 'open', 'open', '#FF0000', 1, 0, 0, 0, 0, 0, 0, 0);");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (ID, ShortNameContentKey, TicketViewContentKey, TextColor, IsNewTicketStatus, IsClosed, IsClosedByClient, IsCustomerReplyStatus,
IsStaffClosedOption, IsStaffReopenedStatus, IsDefaultStaffReplyStatus, LockedTicketStatus)
VALUES (1, 'wait_reply', 'wait_staff_reply', '#FF9933', 0, 0, 0, 1, 0, 1, 0, 0);");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (ID, ShortNameContentKey, TicketViewContentKey, TextColor, IsNewTicketStatus, IsClosed, IsClosedByClient, IsCustomerReplyStatus,
IsStaffClosedOption, IsStaffReopenedStatus, IsDefaultStaffReplyStatus, LockedTicketStatus)
VALUES (2, 'replied', 'wait_cust_reply', '#0000FF', 0, 0, 0, 0, 0, 0, 1, 0);");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (ID, ShortNameContentKey, TicketViewContentKey, TextColor, IsNewTicketStatus, IsClosed, IsClosedByClient, IsCustomerReplyStatus,
IsStaffClosedOption, IsStaffReopenedStatus, IsDefaultStaffReplyStatus, LockedTicketStatus)
VALUES (3, 'resolved', 'resolved', '#008000', 0, 1, 1, 0, 1, 0, 0, 1);");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (ID, ShortNameContentKey, TicketViewContentKey, TextColor, IsNewTicketStatus, IsClosed, IsClosedByClient, IsCustomerReplyStatus,
IsStaffClosedOption, IsStaffReopenedStatus, IsDefaultStaffReplyStatus, LockedTicketStatus)
VALUES (4, 'in_progress', 'in_progress', '#000000', 0, 0, 0, 0, 0, 0, 0, 0);");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` (ID, ShortNameContentKey, TicketViewContentKey, TextColor, IsNewTicketStatus, IsClosed, IsClosedByClient, IsCustomerReplyStatus,
IsStaffClosedOption, IsStaffReopenedStatus, IsDefaultStaffReplyStatus, LockedTicketStatus)
VALUES (5, 'on_hold', 'on_hold', '#000000', 0, 0, 0, 0, 0, 0, 0, 0);");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses`");
}
}

@ -0,0 +1,20 @@
<?php
namespace Pre140\Statuses;
use AbstractMigration;
class MoveStatusesToNewColumn extends AbstractMigration {
function up($hesk_settings) {
$ticketsRS = $this->executeQuery("SELECT `id`, `status` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets`;");
while ($currentResult = hesk_dbFetchAssoc($ticketsRS)) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` SET `status_int` = " . $currentResult['status'] . " WHERE `id` = " . $currentResult['id']);
}
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` CHANGE COLUMN `status_int` `status` INT NOT NULL");
}
}

@ -0,0 +1,15 @@
<?php
namespace Pre140\Statuses;
class RenameTempColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` CHANGE COLUMN `status_int` `status` INT NOT NULL");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `status`");
}
}

@ -0,0 +1,21 @@
<?php
class UpdateMigration extends AbstractUpdatableMigration {
private $upVersion;
private $downVersion;
public function __construct($upVersion, $downVersion, $migrationNumber) {
parent::__construct($migrationNumber);
$this->upVersion = $upVersion;
$this->downVersion = $downVersion;
}
function innerUp($hesk_settings) {
$this->updateVersion($this->upVersion, $hesk_settings);
}
function innerDown($hesk_settings) {
$this->updateVersion($this->downVersion, $hesk_settings);
}
}

@ -0,0 +1,217 @@
<?php
set_error_handler(function($errorNumber, $errorMessage, $errorFile, $errorLine) {
output("An error occurred: {$errorMessage} in {$errorFile} on {$errorLine}",
500,
"Content-Type: text/plain");
});
spl_autoload_register(function ($class) {
// USED FOR MIGRATIONS
$file = HESK_PATH . 'install/migrations/' . str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require($file);
} else {
output(array("message" => "{$file} not found!", 500));
}
});
function getAllMigrations() {
return array(
1 => new \Pre140\Statuses\AddIntColumnUpDropTableDown(),
2 => new \Pre140\Statuses\MoveStatusesToNewColumn(),
3 => new \Pre140\Statuses\DropOldStatusColumn(),
4 => new \Pre140\Statuses\RenameTempColumn(),
5 => new \Pre140\Statuses\CreateStatusesTable(),
6 => new \Pre140\Statuses\InsertStatusRecords(),
//1.4.0
7 => new \v140\AddAutorefreshColumn(),
8 => new \v140\AddDeniedIpsTable(),
//1.4.1
9 => new \v141\AddDeniedEmailsTable(),
10 => new \v141\AddTicketParentColumn(),
//1.5.0
11 => new \v150\AddActiveColumnToUser(),
12 => new \v150\AddCanManSettingsPermissionToUser(),
13 => new \v150\AddDefaultNotifyCustomerEmailPreference(),
//1.6.0
14 => new \v160\AddNotifyNoteUnassignedProperty(),
15 => new \v160\AddCanChangeNotificationSettingsPermission(),
16 => new \v160\AddEditInfoToNotes\AddEditDateColumn(),
17 => new \v160\AddEditInfoToNotes\AddNumberOfEditsColumn(),
18 => new \v160\AddNoteIdToAttachments(),
19 => new \v160\ModifyTicketIdOnAttachments(),
20 => new \v160\CreateSettingsTable(),
21 => new \v160\InsertVersionRecord(),
//1.6.1
22 => new LegacyUpdateMigration('1.6.1', '1.6.0'),
//1.7.0
23 => new \v170\CreateVerifiedEmailsTable(),
24 => new \v170\CreatePendingVerificationEmailsTable(),
25 => new \v170\CreateStageTicketsTable(),
26 => new LegacyUpdateMigration('1.7.0', '1.6.1'),
//2.0.0
27 => new \v200\RemoveNoteIdFromAttachments(),
28 => new \v200\RemoveEditInfoFromNotes\DropEditDate(),
29 => new \v200\RemoveEditInfoFromNotes\DropNumberOfEditsColumn(),
30 => new \v200\RemoveDefaultNotifyCustomerEmailPreference(),
31 => new \v200\AddMissingKeyToTickets(),
32 => new \v200\MigrateIpAndEmailBans\InsertIpBans(),
33 => new \v200\MigrateIpAndEmailBans\InsertEmailBans(),
34 => new \v200\MigrateIpAndEmailBans\DropOldEmailBansTable(),
35 => new \v200\MigrateIpAndEmailBans\DropOldIpBansTable(),
36 => new LegacyUpdateMigration('2.0.0', '1.7.0'),
//2.0.1
37 => new LegacyUpdateMigration('2.0.1', '2.0.0'),
//2.1.0
38 => new LegacyUpdateMigration('2.1.0', '2.0.1'),
//2.1.1
39 => new \v211\FixStageTicketsTable\ChangeDtColumnType(),
40 => new \v211\FixStageTicketsTable\FixStageTicketsTable(),
41 => new LegacyUpdateMigration('2.1.1', '2.1.0'),
//2.2.0
42 => new \v220\AddIsAutocloseOptionToStatuses\AddNewColumn(),
43 => new \v220\AddIsAutocloseOptionToStatuses\SetDefaultValue(),
44 => new \v220\AddClosableColumnToStatuses\AddNewColumn(),
45 => new \v220\AddClosableColumnToStatuses\SetDefaultValue(),
46 => new LegacyUpdateMigration('2.2.0', '2.1.1'),
//2.2.1
47 => new LegacyUpdateMigration('2.2.1', '2.2.0'),
//2.3.0
48 => new \v230\AddIconToServiceMessages(),
49 => new \v230\ConsolidateStatusColumns\AddKeyColumn(),
50 => new \v230\ConsolidateStatusColumns\SetNewKeyColumnValue(),
51 => new \v230\ConsolidateStatusColumns\DropShortNameColumn(),
52 => new \v230\ConsolidateStatusColumns\DropTicketViewContentKeyColumn(),
53 => new \v230\AddCoordinatesToTickets\AddLatitudeToTickets(),
54 => new \v230\AddCoordinatesToTickets\AddLongitudeToTickets(),
55 => new \v230\AddCoordinatesToTickets\AddLatitudeToStageTickets(),
56 => new \v230\AddCoordinatesToTickets\AddLongitudeToStageTickets(),
57 => new \v230\AddCategoryManager(),
58 => new \v230\MovePermissionsToHeskPrivilegesColumn\CopyCanManSettings(),
59 => new \v230\MovePermissionsToHeskPrivilegesColumn\CopyCanChangeNotificationSettings(),
60 => new \v230\MovePermissionsToHeskPrivilegesColumn\DropCanManSettingsColumn(),
61 => new \v230\MovePermissionsToHeskPrivilegesColumn\DropCanChangeNotificationSettingsColumn(),
62 => new \v230\CreatePermissionTemplates\AddPermissionTemplateColumn(),
63 => new \v230\CreatePermissionTemplates\CreatePermissionTemplatesTable(),
64 => new \v230\CreatePermissionTemplates\InsertAdminPermissionTemplate(),
65 => new \v230\CreatePermissionTemplates\InsertStaffPermissionTemplate(),
66 => new \v230\CreatePermissionTemplates\UpdateAdminUsersTemplate(),
67 => new LegacyUpdateMigration('2.3.0', '2.2.1'),
//2.3.1
68 => new LegacyUpdateMigration('2.3.1', '2.3.0'),
//2.3.2
69 => new LegacyUpdateMigration('2.3.2', '2.3.1'),
//2.4.0
70 => new \v240\CreateQuickHelpSections\CreateTable(),
71 => new \v240\CreateQuickHelpSections\InsertCreateTicketRecord(),
72 => new \v240\CreateQuickHelpSections\InsertKnowledgebaseRecord(),
73 => new \v240\CreateQuickHelpSections\InsertStaffCreateTicketRecord(),
74 => new \v240\CreateQuickHelpSections\InsertViewTicketFormRecord(),
75 => new \v240\CreateQuickHelpSections\InsertViewTicketRecord(),
76 => new \v240\CreateNewStatusNameTable\CreateTextToStatusXrefTable(),
77 => new \v240\CreateNewStatusNameTable\AddSortColumnToStatuses(),
78 => new \v240\CreateNewStatusNameTable\UpdateSortValues(),
79 => new \v240\CreateNewStatusNameTable\InsertTextToStatusXrefValues(),
80 => new \v240\AddDownloadCountToAttachments\AddToAttachmentsTable(),
81 => new \v240\AddDownloadCountToAttachments\AddToKBAttachmentsTable(),
82 => new \v240\AddHtmlColumnToTickets\UpdateTicketsTable(),
83 => new \v240\AddHtmlColumnToTickets\UpdateStageTicketsTable(),
84 => new \v240\AddHtmlColumnToTickets\UpdateRepliesTable(),
85 => new LegacyUpdateMigration('2.4.0', '2.3.2'),
//2.4.1
86 => new LegacyUpdateMigration('2.4.1', '2.4.0'),
//2.4.2
87 => new LegacyUpdateMigration('2.4.2', '2.4.1'),
//2.5.0
88 => new \v250\MigrateSettingsToDatabase(),
89 => new \v250\AddUserAgentAndScreenResToTickets\AddUserAgentToTickets(),
90 => new \v250\AddUserAgentAndScreenResToTickets\AddUserAgentToStageTickets(),
91 => new \v250\AddUserAgentAndScreenResToTickets\AddScreenResWidthToTickets(),
92 => new \v250\AddUserAgentAndScreenResToTickets\AddScreenResHeightToTickets(),
93 => new \v250\AddUserAgentAndScreenResToTickets\AddScreenResWidthToStageTickets(),
94 => new \v250\AddUserAgentAndScreenResToTickets\AddScreenResHeightToStageTickets(),
95 => new \v250\AddUserAgentAndScreenResToTickets\InsertSetting(),
96 => new \v250\AddNavbarTitleUrl(),
97 => new LegacyUpdateMigration('2.5.0', '2.4.2'),
//2.5.1
98 => new LegacyUpdateMigration('2.5.1', '2.5.0'),
//2.5.2
99 => new LegacyUpdateMigration('2.5.2', '2.5.1'),
//2.5.3
100 => new LegacyUpdateMigration('2.5.3', '2.5.2'),
//2.5.4
101 => new LegacyUpdateMigration('2.5.4', '2.5.3'),
//2.5.5
102 => new LegacyUpdateMigration('2.5.5', '2.5.4'),
//2.6.0
103 => new \v260\AddApiTables\CreateTable(),
104 => new \v260\AddApiTables\InsertSetting(),
105 => new \v260\AddLoggingTable(),
106 => new \v260\AddTempAttachmentTable(),
107 => new \v260\AddCalendarModule\CreateCalendarEventTable(),
108 => new \v260\AddCalendarModule\CreateCalendarEventReminderTable(),
109 => new \v260\AddCalendarModule\AddDueDateColumnToTickets(),
110 => new \v260\AddCalendarModule\AddOverdueEmailSentColumnToTickets(),
111 => new \v260\AddCalendarModule\AddColorColumnToCategories(),
112 => new \v260\AddCalendarModule\AddUsageColumnToCategories(),
113 => new \v260\AddCalendarModule\AddNotifyOverdueUnassignedColumnToUsers(),
114 => new \v260\AddCalendarModule\AddDefaultCalendarViewToUsers(),
115 => new \v260\AddCalendarModule\InsertEnableCalendarSetting(),
116 => new \v260\AddCalendarModule\InsertFirstDayOfWeekSetting(),
117 => new \v260\AddCalendarModule\InsertDefaultCalendarViewSetting(),
118 => new \v260\AddPrimaryKeyToSettings(),
119 => new \v260\ConvertStatusPropertiesToInts(),
120 => new LegacyUpdateMigration('2.6.0', '2.5.5'),
//2.6.1
121 => new LegacyUpdateMigration('2.6.1', '2.6.0'),
//2.6.2
122 => new \v262\AddMissingColumnsToStageTickets\AddDueDateColumn(),
123 => new \v262\AddMissingColumnsToStageTickets\AddOverdueEmailSentColumn(),
124 => new LegacyUpdateMigration('2.6.2', '2.6.1'),
//2.6.3
125 => new LegacyUpdateMigration('2.6.3', '2.6.2'),
//2.6.4
126 => new LegacyUpdateMigration('2.6.4', '2.6.3'),
//3.0.0
127 => new \v300\MigrateHeskCustomStatuses(),
128 => new \v300\MigrateAutorefreshOption\UpdateFromOldValue(),
129 => new \v300\MigrateAutorefreshOption\DropOldColumn(),
130 => new \v300\AddColorSchemeSetting(),
131 => new LegacyUpdateMigration('3.0.0', '2.6.4'),
//3.0.1
132 => new LegacyUpdateMigration('3.0.1', '3.0.0'),
//3.0.2
133 => new \v302\AddMissingCustomFields(),
134 => new LegacyUpdateMigration('3.0.2', '3.0.1'),
//3.0.3 - 3.0.7
135 => new LegacyUpdateMigration('3.0.3', '3.0.2'),
136 => new LegacyUpdateMigration('3.0.4', '3.0.3'),
137 => new LegacyUpdateMigration('3.0.5', '3.0.4'),
138 => new LegacyUpdateMigration('3.0.6', '3.0.5'),
139 => new LegacyUpdateMigration('3.0.7', '3.0.6'),
//3.1.0
140 => new \v310\AddStackTraceToLogs(),
141 => new \v310\AddCustomNavElements\CreateCustomNavElementTable(),
142 => new \v310\AddCustomNavElements\CreateCustomNavElementToTextTable(),
143 => new \v310\AddMoreColorOptionsToCategories\AddForegroundColor(),
144 => new \v310\AddMoreColorOptionsToCategories\AddDisplayBorderOutline(),
145 => new \v310\AddMoreColorOptionsToCategories\AddBackgroundColor(),
146 => new \v310\AddNewLoginSettings\AddLoginBackgroundType(),
147 => new \v310\AddNewLoginSettings\AddLoginBackground(),
148 => new \v310\AddNewLoginSettings\AddLoginBoxHeader(),
149 => new \v310\AddNewLoginSettings\AddLoginBoxHeaderImage(),
150 => new \v310\AddApiUrlRewriteSetting(),
151 => new \v310\ConvertPresetToIndividualColors(),
152 => new LegacyUpdateMigration('3.1.0', '3.0.7'),
//3.1.1
153 => new LegacyUpdateMigration('3.1.1', '3.1.0'),
//3.2.0
154 => new \v320\AddDescriptionToCategoriesAndCustomFields\AddDescriptionToCategories(),
155 => new \v320\AddDescriptionToCategoriesAndCustomFields\AddDescriptionToCustomFields(),
156 => new \v320\AddAuditTrail\CreateAuditTrailTable(),
157 => new \v320\AddAuditTrail\CreateAuditTrailToReplacementValuesTable(),
158 => new \v320\AddMigrationSetting(),
159 => new UpdateMigration('3.2.0', '3.1.1', 159),
);
}

@ -0,0 +1,16 @@
<?php
namespace v140;
use AbstractMigration;
class AddAutorefreshColumn extends AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `autorefresh` BIGINT NOT NULL DEFAULT 0 AFTER `replies`;");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `autorefresh`;");
}
}

@ -0,0 +1,17 @@
<?php
namespace v140;
class AddDeniedIpsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_ips` (
`ID` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
`RangeStart` VARCHAR(100) NOT NULL,
`RangeEnd` VARCHAR(100) NOT NULL)");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_ips`");
}
}

@ -0,0 +1,16 @@
<?php
namespace v141;
class AddDeniedEmailsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_emails` (
ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
Email VARCHAR(100) NOT NULL);");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_emails`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v141;
class AddTicketParentColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `parent` MEDIUMINT(8) NULL AFTER `custom20`;");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `parent`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v150;
class AddActiveColumnToUser extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `active` ENUM('0', '1') NOT NULL DEFAULT '1'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `active`");
}
}

@ -0,0 +1,14 @@
<?php
namespace v150;
class AddCanManSettingsPermissionToUser extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `can_manage_settings` ENUM('0', '1') NOT NULL DEFAULT '1'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `can_manage_settings`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v150;
class AddDefaultNotifyCustomerEmailPreference extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `default_notify_customer_email` ENUM ('0', '1') NOT NULL DEFAULT '1'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `default_notify_customer_email`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v160;
class AddCanChangeNotificationSettingsPermission extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `can_change_notification_settings` ENUM('0', '1') NOT NULL DEFAULT '1'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `can_change_notification_settings`");
}
}

@ -0,0 +1,14 @@
<?php
namespace v160\AddEditInfoToNotes;
class AddEditDateColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` ADD COLUMN `edit_date` DATETIME NULL");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` DROP COLUMN `edit_date`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v160\AddEditInfoToNotes;
class AddNumberOfEditsColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` ADD COLUMN `number_of_edits` INT NOT NULL DEFAULT 0");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` DROP COLUMN `number_of_edits`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v160;
class AddNoteIdToAttachments extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` ADD COLUMN `note_id` INT NULL AFTER `ticket_id`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` DROP COLUMN `note_id`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v160;
class AddNotifyNoteUnassignedProperty extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `notify_note_unassigned` ENUM('0', '1') NOT NULL DEFAULT '0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `notify_note_unassigned`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v160;
class CreateSettingsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` (`Key` NVARCHAR(200) NOT NULL, `Value` NVARCHAR(200) NOT NULL)");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v160;
class InsertVersionRecord extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` (`Key`, `Value`) VALUES ('modsForHeskVersion', '1.6.0')");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` WHERE `Key` = 'modsForHeskVersion'");
}
}

@ -0,0 +1,15 @@
<?php
namespace v160;
class ModifyTicketIdOnAttachments extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` MODIFY COLUMN `ticket_id` VARCHAR(13) NULL");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` MODIFY COLUMN `ticket_id` VARCHAR(13) NOT NULL DEFAULT ''");
}
}

@ -0,0 +1,15 @@
<?php
namespace v170;
class CreatePendingVerificationEmailsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "pending_verification_emails` (`Email` VARCHAR(255) NOT NULL, `ActivationKey` VARCHAR(500) NOT NULL)");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "pending_verification_emails`");
}
}

@ -0,0 +1,65 @@
<?php
namespace v170;
class CreateStageTicketsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`trackid` varchar(13) COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`category` smallint(5) unsigned NOT NULL DEFAULT '1',
`priority` enum('0','1','2','3') COLLATE utf8_unicode_ci NOT NULL DEFAULT '3',
`subject` varchar(70) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`message` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`dt` timestamp NOT NULL DEFAULT '2000-01-01 00:00:00',
`lastchange` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`ip` varchar(46) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`language` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`status` int(11) NOT NULL DEFAULT '0',
`owner` smallint(5) unsigned NOT NULL DEFAULT '0',
`time_worked` time NOT NULL DEFAULT '00:00:00',
`lastreplier` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`replierid` smallint(5) unsigned DEFAULT NULL,
`archive` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`locked` enum('0','1') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`attachments` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`merged` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`history` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom1` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom2` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom3` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom4` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom5` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom6` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom7` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom8` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom9` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom10` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom11` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom12` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom13` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom14` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom15` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom16` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom17` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom18` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom19` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`custom20` mediumtext COLLATE utf8_unicode_ci NOT NULL,
`parent` mediumint(8) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `trackid` (`trackid`),
KEY `archive` (`archive`),
KEY `categories` (`category`),
KEY `statuses` (`status`),
KEY `owner` (`owner`)
)");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v170;
class CreateVerifiedEmailsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "verified_emails` (`Email` VARCHAR(255) NOT NULL)");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "verified_emails`");
}
}

@ -0,0 +1,19 @@
<?php
namespace v200;
class AddMissingKeyToTickets extends \AbstractMigration {
function up($hesk_settings) {
$keyRs = $this->executeQuery("SHOW KEYS FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE Key_name='statuses'");
if (hesk_dbNumRows($keyRs) == 0) {
//-- Add the key
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD KEY `statuses` (`status`)");
}
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP INDEX `statuses`");
}
}

@ -0,0 +1,17 @@
<?php
namespace v200\MigrateIpAndEmailBans;
class DropOldEmailBansTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_emails`");
}
function down($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_emails` (
ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
Email VARCHAR(100) NOT NULL);");
}
}

@ -0,0 +1,18 @@
<?php
namespace v200\MigrateIpAndEmailBans;
class DropOldIpBansTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_ips`");
}
function down($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_ips` (
`ID` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
`RangeStart` VARCHAR(100) NOT NULL,
`RangeEnd` VARCHAR(100) NOT NULL)");
}
}

@ -0,0 +1,21 @@
<?php
namespace v200\MigrateIpAndEmailBans;
class InsertEmailBans extends \AbstractMigration {
function up($hesk_settings) {
$emailBanRS = $this->executeQuery("SELECT `Email` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_emails`");
while ($row = hesk_dbFetchAssoc($emailBanRS)) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "banned_emails` (`email`, `banned_by`, `dt`)
VALUES ('" . hesk_dbEscape($row['Email']) . "', 1, NOW())");
}
}
function down($hesk_settings) {
$emails = $this->executeQuery("SELECT `email` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "banned_emails`");
while ($row = hesk_dbFetchAssoc($emails)) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_emails` (Email) VALUES ('" . hesk_dbEscape($row['email']) . "')");
}
}
}

@ -0,0 +1,25 @@
<?php
namespace v200\MigrateIpAndEmailBans;
class InsertIpBans extends \AbstractMigration {
function up($hesk_settings) {
$ipBanRS = $this->executeQuery("SELECT `RangeStart`, `RangeEnd` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_ips`");
while ($row = hesk_dbFetchAssoc($ipBanRS)) {
$ipFrom = long2ip($row['RangeStart']);
$ipTo = long2ip($row['RangeEnd']);
$ipDisplay = $ipFrom == $ipTo ? $ipFrom : $ipFrom . ' - ' . $ipTo;
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "banned_ips` (`ip_from`, `ip_to`, `ip_display`, `banned_by`, `dt`)
VALUES (" . $row['RangeStart'] . ", " . $row['RangeEnd'] . ", '" . $ipDisplay . "', 1, NOW())");
}
}
function down($hesk_settings) {
$ips = $this->executeQuery("SELECT `ip_from`, `ip_to` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "banned_ips`");
while ($row = hesk_dbFetchAssoc($ips)) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "denied_ips` (`RangeStart`, `RangeEnd`) VALUES (" . $row['ip_from'] . ", " . $row['ip_to'] . ")");
}
}
}

@ -0,0 +1,15 @@
<?php
namespace v200;
class RemoveDefaultNotifyCustomerEmailPreference extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `default_notify_customer_email`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `default_notify_customer_email` ENUM ('0', '1') NOT NULL DEFAULT '1'");
}
}

@ -0,0 +1,14 @@
<?php
namespace v200\RemoveEditInfoFromNotes;
class DropEditDate extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` DROP COLUMN `edit_date`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` ADD COLUMN `edit_date` DATETIME NULL");
}
}

@ -0,0 +1,15 @@
<?php
namespace v200\RemoveEditInfoFromNotes;
class DropNumberOfEditsColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` DROP COLUMN `number_of_edits`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "notes` ADD COLUMN `number_of_edits` INT NOT NULL DEFAULT 0");
}
}

@ -0,0 +1,15 @@
<?php
namespace v200;
class RemoveNoteIdFromAttachments extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` DROP COLUMN `note_id`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` ADD COLUMN `note_id` INT NULL AFTER `ticket_id`");
}
}

@ -0,0 +1,14 @@
<?php
namespace v211\FixStageTicketsTable;
class ChangeDtColumnType extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` CHANGE `dt` `dt` TIMESTAMP NOT NULL DEFAULT '2000-01-01 00:00:00'");
}
function down($hesk_settings) {
// NOOP
}
}

@ -0,0 +1,35 @@
<?php
namespace v211\FixStageTicketsTable;
class FixStageTicketsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets`
CHANGE `email` `email` VARCHAR( 1000 ) NOT NULL DEFAULT '',
CHANGE `ip` `ip` VARCHAR(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
ADD `firstreply` TIMESTAMP NULL DEFAULT NULL AFTER `lastchange`,
ADD `closedat` TIMESTAMP NULL DEFAULT NULL AFTER `firstreply`,
ADD `articles` VARCHAR(255) NULL DEFAULT NULL AFTER `closedat`,
ADD `openedby` MEDIUMINT(8) DEFAULT '0' AFTER `status`,
ADD `firstreplyby` SMALLINT(5) UNSIGNED NULL DEFAULT NULL AFTER `openedby`,
ADD `closedby` MEDIUMINT(8) NULL DEFAULT NULL AFTER `firstreplyby`,
ADD `replies` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `closedby`,
ADD `staffreplies` SMALLINT( 5 ) UNSIGNED NOT NULL DEFAULT '0' AFTER `replies`,
ADD INDEX ( `openedby` , `firstreplyby` , `closedby` ),
ADD INDEX(`dt`)");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets`
CHANGE `email` `email` VARCHAR(255) NOT NULL DEFAULT '',
CHANGE `ip` `ip` VARCHAR(46) NOT NULL DEFAULT '',
DROP `firstreply`,
DROP `closedat`,
DROP `articles`,
DROP `firstreplyby`,
DROP `closedby`,
DROP `replies`,
DROP `staffreplies`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v220\AddClosableColumnToStatuses;
class AddNewColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ADD COLUMN `Closable` VARCHAR(10) NOT NULL");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` DROP COLUMN `Closable`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v220\AddClosableColumnToStatuses;
class SetDefaultValue extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET `Closable` = 'yes'");
}
function down($hesk_settings) {
// no-op
}
}

@ -0,0 +1,14 @@
<?php
namespace v220\AddIsAutocloseOptionToStatuses;
class AddNewColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ADD COLUMN `IsAutocloseOption` INT NOT NULL DEFAULT 0");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` DROP COLUMN `IsAutocloseOption`");
}
}

@ -0,0 +1,14 @@
<?php
namespace v220\AddIsAutocloseOptionToStatuses;
class SetDefaultValue extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET `IsAutocloseOption` = 1 WHERE `IsStaffClosedOption` = 1");
}
function down($hesk_settings) {
// no-op
}
}

@ -0,0 +1,15 @@
<?php
namespace v230;
class AddCategoryManager extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` ADD COLUMN `manager` INT NOT NULL DEFAULT 0");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` DROP COLUMN `manager`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\AddCoordinatesToTickets;
class AddLatitudeToStageTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` ADD COLUMN `latitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` DROP COLUMN `latitude`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\AddCoordinatesToTickets;
class AddLatitudeToTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `latitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `latitude`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\AddCoordinatesToTickets;
class AddLongitudeToStageTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` ADD COLUMN `longitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` DROP COLUMN `longitude`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\AddCoordinatesToTickets;
class AddLongitudeToTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `longitude` VARCHAR(100) NOT NULL DEFAULT 'E-0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `longitude`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230;
class AddIconToServiceMessages extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` ADD COLUMN `icon` VARCHAR(150)");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "service_messages` DROP COLUMN `icon`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\ConsolidateStatusColumns;
class AddKeyColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ADD COLUMN `Key` TEXT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` DROP COLUMN `Key`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\ConsolidateStatusColumns;
class DropShortNameColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` DROP COLUMN `ShortNameContentKey`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ADD COLUMN `ShortNameContentKey` TEXT");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\ConsolidateStatusColumns;
class DropTicketViewContentKeyColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` DROP COLUMN `TicketViewContentKey`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ADD COLUMN `TicketViewContentKey` TEXT");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\ConsolidateStatusColumns;
class SetNewKeyColumnValue extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET `Key` = `ShortNameContentKey`");
}
function down($hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET `TicketViewContentKey` = `Key`, `ShortNameContentKey` = `Key`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\CreatePermissionTemplates;
class AddPermissionTemplateColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `permission_template` INT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `permission_template`");
}
}

@ -0,0 +1,18 @@
<?php
namespace v230\CreatePermissionTemplates;
class CreatePermissionTemplatesTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(255) NOT NULL,
`heskprivileges` VARCHAR(1000),
`categories` VARCHAR(500))");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\CreatePermissionTemplates;
class InsertAdminPermissionTemplate extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` (`name`, `heskprivileges`, `categories`)
VALUES ('Administrator', 'ALL', 'ALL')");
}
function down($hesk_settings) {
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\CreatePermissionTemplates;
class InsertStaffPermissionTemplate extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "permission_templates` (`name`, `heskprivileges`, `categories`)
VALUES ('Staff', 'can_view_tickets,can_reply_tickets,can_change_cat,can_assign_self,can_view_unassigned,can_view_online', '1')");
}
function down($hesk_settings) {
}
}

@ -0,0 +1,14 @@
<?php
namespace v230\CreatePermissionTemplates;
class UpdateAdminUsersTemplate extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `permission_template` = 1 WHERE `isadmin` = '1'");
}
function down($hesk_settings) {
}
}

@ -0,0 +1,30 @@
<?php
namespace v230\MovePermissionsToHeskPrivilegesColumn;
class CopyCanChangeNotificationSettings extends \AbstractMigration {
function up($hesk_settings) {
$res = $this->executeQuery("SELECT `id`, `heskprivileges` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `isadmin` = '0'
AND `can_change_notification_settings` = '1'");
while ($row = hesk_dbFetchAssoc($res)) {
if ($row['heskprivileges'] != '') {
$currentPrivileges = explode(',', $row['heskprivileges']);
array_push($currentPrivileges, 'can_change_notification_settings');
$newPrivileges = implode(',', $currentPrivileges);
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `heskprivileges` = '" . hesk_dbEscape($newPrivileges) . "'
WHERE `id` = " . intval($row['id']));
} else {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `heskprivileges` = 'can_change_notification_settings'
WHERE `id` = " . intval($row['id']));
}
}
}
function down($hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users`
SET `can_change_notification_settings` = '0'
WHERE `heskprivileges` NOT LIKE '%can_change_notification_settings%'");
}
}

@ -0,0 +1,31 @@
<?php
namespace v230\MovePermissionsToHeskPrivilegesColumn;
class CopyCanManSettings extends \AbstractMigration {
function up($hesk_settings) {
// Move can_manage_settings and can_change_notification_settings into the heskprivileges list
$res = $this->executeQuery("SELECT `id`, `heskprivileges` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` WHERE `isadmin` = '0'
AND `can_manage_settings` = '1'");
while ($row = hesk_dbFetchAssoc($res)) {
if ($row['heskprivileges'] != '') {
$currentPrivileges = explode(',', $row['heskprivileges']);
array_push($currentPrivileges, 'can_man_settings');
$newPrivileges = implode(',', $currentPrivileges);
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `heskprivileges` = '" . hesk_dbEscape($newPrivileges) . "'
WHERE `id` = " . intval($row['id']));
} else {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` SET `heskprivileges` = 'can_man_settings'
WHERE `id` = " . intval($row['id']));
}
}
}
function down($hesk_settings) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users`
SET `can_manage_settings` = '0'
WHERE `heskprivileges` NOT LIKE '%can_man_settings%'");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\MovePermissionsToHeskPrivilegesColumn;
class DropCanChangeNotificationSettingsColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `can_change_notification_settings`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `can_change_notification_settings` ENUM('0', '1') NOT NULL DEFAULT '1'");
}
}

@ -0,0 +1,15 @@
<?php
namespace v230\MovePermissionsToHeskPrivilegesColumn;
class DropCanManSettingsColumn extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` DROP COLUMN `can_manage_settings`");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ADD COLUMN `can_manage_settings` ENUM ('0', '1') NOT NULL DEFAULT '1'");
}
}

@ -0,0 +1,15 @@
<?php
namespace v240\AddDownloadCountToAttachments;
class AddToAttachmentsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` ADD COLUMN `download_count` INT NOT NULL DEFAULT 0");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "attachments` DROP COLUMN `download_count`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v240\AddDownloadCountToAttachments;
class AddToKBAttachmentsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "kb_attachments` ADD COLUMN `download_count` INT NOT NULL DEFAULT 0");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "kb_attachments` DROP COLUMN `download_count`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v240\AddHtmlColumnToTickets;
class UpdateRepliesTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` ADD COLUMN `html` ENUM('0','1') NOT NULL DEFAULT '0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` DROP COLUMN `html`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v240\AddHtmlColumnToTickets;
class UpdateStageTicketsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` ADD COLUMN `html` ENUM('0','1') NOT NULL DEFAULT '0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` DROP COLUMN `html`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v240\AddHtmlColumnToTickets;
class UpdateTicketsTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `html` ENUM('0','1') NOT NULL DEFAULT '0'");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `html`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v240\CreateNewStatusNameTable;
class AddSortColumnToStatuses extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ADD COLUMN `sort` INT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` DROP COLUMN `sort`");
}
}

@ -0,0 +1,19 @@
<?php
namespace v240\CreateNewStatusNameTable;
class CreateTextToStatusXrefTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`language` VARCHAR(200) NOT NULL,
`text` VARCHAR(200) NOT NULL,
`status_id` INT NOT NULL) ENGINE = MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref`");
}
}

@ -0,0 +1,34 @@
<?php
namespace v240\CreateNewStatusNameTable;
class InsertTextToStatusXrefValues extends \AbstractMigration {
function up($hesk_settings) {
global $hesklang;
$languages = array();
foreach ($hesk_settings['languages'] as $key => $value) {
$languages[$key] = $hesk_settings['languages'][$key]['folder'];
}
$statusesRs = $this->executeQuery("SELECT `ID`, `Key` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses`");
$oldSetting = $hesk_settings['can_sel_lang'];
$hesk_settings['can_sel_lang'] = 1;
while ($row = hesk_dbFetchAssoc($statusesRs)) {
foreach ($languages as $language => $languageCode) {
hesk_setLanguage($language);
$sql = "INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref` (`language`, `text`, `status_id`)
VALUES ('" . hesk_dbEscape($language) . "', '" . hesk_dbEscape($hesklang[$row['Key']]) . "', " . intval($row['ID']) . ")";
$this->executeQuery($sql);
}
}
$hesk_settings['can_sel_lang'] = $oldSetting;
hesk_resetLanguage();
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "text_to_status_xref`");
}
}

@ -0,0 +1,20 @@
<?php
namespace v240\CreateNewStatusNameTable;
class UpdateSortValues extends \AbstractMigration {
function up($hesk_settings) {
$statusesRs = $this->executeQuery("SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` ORDER BY `ID` ASC");
$i = 10;
while ($myStatus = hesk_dbFetchAssoc($statusesRs)) {
$this->executeQuery("UPDATE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` SET `sort`=" . intval($i) . "
WHERE `id`='" . intval($myStatus['ID']) . "' LIMIT 1");
$i += 10;
}
}
function down($hesk_settings) {
}
}

@ -0,0 +1,30 @@
<?php
namespace v240\CreateQuickHelpSections;
class CreateTable extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("CREATE TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`location` VARCHAR(100) NOT NULL,
`show` ENUM('0','1') NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('create_ticket', '1')");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('view_ticket_form', '1')");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('view_ticket', '1')");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('knowledgebase', '1')");
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('staff_create_ticket', '1')");
}
function down($hesk_settings) {
$this->executeQuery("DROP TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections`");
}
}

@ -0,0 +1,17 @@
<?php
namespace v240\CreateQuickHelpSections;
class InsertCreateTicketRecord extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('create_ticket', '1')");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections`
WHERE `location` = 'create_ticket'");
}
}

@ -0,0 +1,17 @@
<?php
namespace v240\CreateQuickHelpSections;
class InsertKnowledgebaseRecord extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('knowledgebase', '1')");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections`
WHERE `location` = 'knowledgebase'");
}
}

@ -0,0 +1,17 @@
<?php
namespace v240\CreateQuickHelpSections;
class InsertStaffCreateTicketRecord extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('staff_create_ticket', '1')");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections`
WHERE `location` = 'staff_create_ticket'");
}
}

@ -0,0 +1,17 @@
<?php
namespace v240\CreateQuickHelpSections;
class InsertViewTicketFormRecord extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('view_ticket_form', '1')");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections`
WHERE `location` = 'view_ticket_form'");
}
}

@ -0,0 +1,17 @@
<?php
namespace v240\CreateQuickHelpSections;
class InsertViewTicketRecord extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections` (`location`, `show`)
VALUES ('view_ticket', '1')");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "quick_help_sections`
WHERE `location` = 'view_ticket'");
}
}

@ -0,0 +1,15 @@
<?php
namespace v250;
class AddNavbarTitleUrl extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("INSERT INTO `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` (`Key`, `Value`) VALUES ('navbar_title_url', '" . hesk_dbEscape($hesk_settings['hesk_url']) . "')");
}
function down($hesk_settings) {
$this->executeQuery("DELETE FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "settings` WHERE `Key` = 'navbar_title_url'");
}
}

@ -0,0 +1,15 @@
<?php
namespace v250\AddUserAgentAndScreenResToTickets;
class AddScreenResHeightToStageTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` ADD COLUMN `screen_resolution_height` INT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` DROP COLUMN `screen_resolution_height`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v250\AddUserAgentAndScreenResToTickets;
class AddScreenResHeightToTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `screen_resolution_height` INT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `screen_resolution_height`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v250\AddUserAgentAndScreenResToTickets;
class AddScreenResWidthToStageTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` ADD COLUMN `screen_resolution_width` INT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` DROP COLUMN `screen_resolution_width`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v250\AddUserAgentAndScreenResToTickets;
class AddScreenResWidthToTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `screen_resolution_width` INT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `screen_resolution_width`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v250\AddUserAgentAndScreenResToTickets;
class AddUserAgentToStageTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` ADD COLUMN `user_agent` TEXT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "stage_tickets` DROP COLUMN `user_agent`");
}
}

@ -0,0 +1,15 @@
<?php
namespace v250\AddUserAgentAndScreenResToTickets;
class AddUserAgentToTickets extends \AbstractMigration {
function up($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ADD COLUMN `user_agent` TEXT");
}
function down($hesk_settings) {
$this->executeQuery("ALTER TABLE `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` DROP COLUMN `user_agent`");
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save