diff --git a/.gitignore b/.gitignore index 32828f4a..bdfa288b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ admin/archive.php admin/assign_owner.php admin/generate_spam_question.php admin/move_category.php -admin/options.php admin/priority.php admin/test_connection.php attachments/index.htm diff --git a/README.md b/README.md index c6e37e35..7298a3c9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Stories in Ready](https://badge.waffle.io/mkoch227/Mods-For-Hesk.png?label=waffle:ready&title=Ready)](https://waffle.io/mkoch227/Mods-For-Hesk) -
Please consult the official HESK Documentation on how to install HESK, as it is the same for both HESK and Mods for HESK.
+Visit http://mods-for-hesk.mkochcs.com/download.php for installation instructions.
As of current, only English is a supported language, as there have been several language items that have been edited/created. If you want to translate Mods for HESK to your own language, it is recommended to download the original HESK language file for your language, and then add/edit the lines listed under //Added or modified in Mods for HESK X.X.X (where X.X.X is a version number) for your language.
@@ -141,10 +141,10 @@ if ( defined('HESK_DEMO') ) ?> | ||||||||||||||||||||||||||||||||
+ | : | -+ | + | |||||||||||||||||||||||||||||
+ : + | + + | |||||||||||||||||||||||||||||||
/hesk_settings.inc.php @@ -1215,7 +1220,9 @@ if ( defined('HESK_DEMO') ) | - | + | + + | @@ -1670,7 +1679,24 @@ if ( defined('HESK_DEMO') ) |
---|
'.$hesklang['custom_l'].': | + | + |
'.$hesklang['defw'].': | + | + |
'.$hesklang['rows'].': | + | + |
'.$hesklang['cols'].': | + | + |
'.$hesklang['opt2'].'
+ + + '; + break; + case 'select': + $options=str_replace('#HESK#',"\n",$query); + echo ' + + +'.$hesklang['opt3'].'
+ + + '; + break; + case 'checkbox': + $options=str_replace('#HESK#',"\n",$query); + echo ' + + +'.$hesklang['opt4'].'
+ + + '; + break; + case 'date': + echo ''.$hesklang['date_custom_field_text'].'
'; + break; + case 'multiselect': + $options=str_replace('#HESK#',"\n",$query); + echo ' + + +'.$hesklang['multiple_select_custom_field_text'].'
+ + + '; + break; + default: + die('Invalid type'); +} +?> + + + ++ + + + + diff --git a/css/datepicker.css b/css/datepicker.css new file mode 100755 index 00000000..6d37209e --- /dev/null +++ b/css/datepicker.css @@ -0,0 +1,510 @@ +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ +.datepicker { + padding: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + direction: ltr; +} +.datepicker-inline { + width: 220px; +} +.datepicker.datepicker-rtl { + direction: rtl; +} +.datepicker.datepicker-rtl table tr td span { + float: right; +} +.datepicker-dropdown { + top: 0; + left: 0; +} +.datepicker-dropdown:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-top: 0; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; +} +.datepicker-dropdown:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-top: 0; + position: absolute; +} +.datepicker-dropdown.datepicker-orient-left:before { + left: 6px; +} +.datepicker-dropdown.datepicker-orient-left:after { + left: 7px; +} +.datepicker-dropdown.datepicker-orient-right:before { + right: 6px; +} +.datepicker-dropdown.datepicker-orient-right:after { + right: 7px; +} +.datepicker-dropdown.datepicker-orient-top:before { + top: -7px; +} +.datepicker-dropdown.datepicker-orient-top:after { + top: -6px; +} +.datepicker-dropdown.datepicker-orient-bottom:before { + bottom: -7px; + border-bottom: 0; + border-top: 7px solid #999; +} +.datepicker-dropdown.datepicker-orient-bottom:after { + bottom: -6px; + border-bottom: 0; + border-top: 6px solid #ffffff; +} +.datepicker > div { + display: none; +} +.datepicker.days div.datepicker-days { + display: block; +} +.datepicker.months div.datepicker-months { + display: block; +} +.datepicker.years div.datepicker-years { + display: block; +} +.datepicker table { + margin: 0; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.datepicker td, +.datepicker th { + text-align: center; + width: 20px; + height: 20px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + border: none; +} +.table-striped .datepicker table tr td, +.table-striped .datepicker table tr th { + background-color: transparent; +} +.datepicker table tr td.day:hover, +.datepicker table tr td.day.focused { + background: #eeeeee; + cursor: pointer; +} +.datepicker table tr td.old, +.datepicker table tr td.new { + color: #999999; +} +.datepicker table tr td.disabled, +.datepicker table tr td.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td.today, +.datepicker table tr td.today:hover, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:hover { + background-color: #fde19a; + background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a)); + background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -o-linear-gradient(top, #fdd49a, #fdf59a); + background-image: linear-gradient(top, #fdd49a, #fdf59a); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0); + border-color: #fdf59a #fdf59a #fbed50; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #000; +} +.datepicker table tr td.today:hover, +.datepicker table tr td.today:hover:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today:hover.disabled, +.datepicker table tr td.today.disabled.disabled, +.datepicker table tr td.today.disabled:hover.disabled, +.datepicker table tr td.today[disabled], +.datepicker table tr td.today:hover[disabled], +.datepicker table tr td.today.disabled[disabled], +.datepicker table tr td.today.disabled:hover[disabled] { + background-color: #fdf59a; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active { + background-color: #fbf069 \9; +} +.datepicker table tr td.today:hover:hover { + color: #000; +} +.datepicker table tr td.today.active:hover { + color: #fff; +} +.datepicker table tr td.range, +.datepicker table tr td.range:hover, +.datepicker table tr td.range.disabled, +.datepicker table tr td.range.disabled:hover { + background: #eeeeee; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.datepicker table tr td.range.today, +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today.disabled:hover { + background-color: #f3d17a; + background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a)); + background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -o-linear-gradient(top, #f3c17a, #f3e97a); + background-image: linear-gradient(top, #f3c17a, #f3e97a); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0); + border-color: #f3e97a #f3e97a #edde34; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today:hover:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today:hover.disabled, +.datepicker table tr td.range.today.disabled.disabled, +.datepicker table tr td.range.today.disabled:hover.disabled, +.datepicker table tr td.range.today[disabled], +.datepicker table tr td.range.today:hover[disabled], +.datepicker table tr td.range.today.disabled[disabled], +.datepicker table tr td.range.today.disabled:hover[disabled] { + background-color: #f3e97a; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active { + background-color: #efe24b \9; +} +.datepicker table tr td.selected, +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected.disabled:hover { + background-color: #9e9e9e; + background-image: -moz-linear-gradient(top, #b3b3b3, #808080); + background-image: -ms-linear-gradient(top, #b3b3b3, #808080); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080)); + background-image: -webkit-linear-gradient(top, #b3b3b3, #808080); + background-image: -o-linear-gradient(top, #b3b3b3, #808080); + background-image: linear-gradient(top, #b3b3b3, #808080); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0); + border-color: #808080 #808080 #595959; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected:hover:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected:hover.disabled, +.datepicker table tr td.selected.disabled.disabled, +.datepicker table tr td.selected.disabled:hover.disabled, +.datepicker table tr td.selected[disabled], +.datepicker table tr td.selected:hover[disabled], +.datepicker table tr td.selected.disabled[disabled], +.datepicker table tr td.selected.disabled:hover[disabled] { + background-color: #808080; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active { + background-color: #666666 \9; +} +.datepicker table tr td.active, +.datepicker table tr td.active:hover, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active.disabled:hover { + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -ms-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(top, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.active:hover, +.datepicker table tr td.active:hover:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active:hover.disabled, +.datepicker table tr td.active.disabled.disabled, +.datepicker table tr td.active.disabled:hover.disabled, +.datepicker table tr td.active[disabled], +.datepicker table tr td.active:hover[disabled], +.datepicker table tr td.active.disabled[disabled], +.datepicker table tr td.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span { + display: block; + width: 23%; + height: 54px; + line-height: 54px; + float: left; + margin: 1%; + cursor: pointer; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.datepicker table tr td span:hover { + background: #eeeeee; +} +.datepicker table tr td span.disabled, +.datepicker table tr td span.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td span.active, +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active.disabled:hover { + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -ms-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(top, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active:hover.disabled, +.datepicker table tr td span.active.disabled.disabled, +.datepicker table tr td span.active.disabled:hover.disabled, +.datepicker table tr td span.active[disabled], +.datepicker table tr td span.active:hover[disabled], +.datepicker table tr td span.active.disabled[disabled], +.datepicker table tr td span.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span.old, +.datepicker table tr td span.new { + color: #999999; +} +.datepicker th.datepicker-switch { + width: 145px; +} +.datepicker thead tr:first-child th, +.datepicker tfoot tr th { + cursor: pointer; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover { + background: #eeeeee; +} +.datepicker .cw { + font-size: 10px; + width: 12px; + padding: 0 2px 0 5px; + vertical-align: middle; +} +.datepicker thead tr:first-child th.cw { + cursor: default; + background-color: transparent; +} +.input-append.date .add-on i, +.input-prepend.date .add-on i { + cursor: pointer; + width: 16px; + height: 16px; +} +.input-daterange input { + text-align: center; +} +.input-daterange input:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-daterange input:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-daterange .add-on { + display: inline-block; + width: auto; + min-width: 16px; + height: 20px; + padding: 4px 5px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + vertical-align: middle; + background-color: #eeeeee; + border: 1px solid #ccc; + margin-left: -5px; + margin-right: -5px; +} +.datepicker.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + float: left; + display: none; + min-width: 160px; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + *border-right-width: 2px; + *border-bottom-width: 2px; + color: #333333; + font-size: 13px; + line-height: 20px; +} +.datepicker.dropdown-menu th, +.datepicker.datepicker-inline th, +.datepicker.dropdown-menu td, +.datepicker.datepicker-inline td { + padding: 4px 5px; +} diff --git a/css/hesk_newStyle.php b/css/hesk_newStyle.php index f77a5f98..6f65ba1b 100644 --- a/css/hesk_newStyle.php +++ b/css/hesk_newStyle.php @@ -364,3 +364,8 @@ div.setupButtons { float: right; } } + +.white-readonly { + cursor: text !important; + background-color: #fff !important; +} diff --git a/img/ui-bg_flat_0_aaaaaa_40x100.png b/img/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 00000000..9869d1fa Binary files /dev/null and b/img/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/img/ui-bg_flat_75_ffffff_40x100.png b/img/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 00000000..94a8e562 Binary files /dev/null and b/img/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/img/ui-bg_glass_55_fbf9ee_1x400.png b/img/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 00000000..f9e28706 Binary files /dev/null and b/img/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/img/ui-bg_glass_65_ffffff_1x400.png b/img/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 00000000..02bcf0ad Binary files /dev/null and b/img/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/img/ui-bg_glass_75_dadada_1x400.png b/img/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 00000000..a2160772 Binary files /dev/null and b/img/ui-bg_glass_75_dadada_1x400.png differ diff --git a/img/ui-bg_glass_75_e6e6e6_1x400.png b/img/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 00000000..4c544ef4 Binary files /dev/null and b/img/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/img/ui-bg_glass_95_fef1ec_1x400.png b/img/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 00000000..32ab7d10 Binary files /dev/null and b/img/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/img/ui-bg_highlight-soft_75_cccccc_1x100.png b/img/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 00000000..bdf5d2c6 Binary files /dev/null and b/img/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/img/ui-icons_222222_256x240.png b/img/ui-icons_222222_256x240.png new file mode 100644 index 00000000..c1cb1170 Binary files /dev/null and b/img/ui-icons_222222_256x240.png differ diff --git a/img/ui-icons_2e83ff_256x240.png b/img/ui-icons_2e83ff_256x240.png new file mode 100644 index 00000000..84b601bf Binary files /dev/null and b/img/ui-icons_2e83ff_256x240.png differ diff --git a/img/ui-icons_454545_256x240.png b/img/ui-icons_454545_256x240.png new file mode 100644 index 00000000..b6db1acd Binary files /dev/null and b/img/ui-icons_454545_256x240.png differ diff --git a/img/ui-icons_888888_256x240.png b/img/ui-icons_888888_256x240.png new file mode 100644 index 00000000..feea0e20 Binary files /dev/null and b/img/ui-icons_888888_256x240.png differ diff --git a/img/ui-icons_cd0a0a_256x240.png b/img/ui-icons_cd0a0a_256x240.png new file mode 100644 index 00000000..ed5b6b09 Binary files /dev/null and b/img/ui-icons_cd0a0a_256x240.png differ diff --git a/inc/email_functions.inc.php b/inc/email_functions.inc.php index d8dc60ac..a347a0a1 100644 --- a/inc/email_functions.inc.php +++ b/inc/email_functions.inc.php @@ -46,6 +46,25 @@ if ($hesk_settings['smtp']) } } +function hesk_notifyCustomerForVerifyEmail($email_template = 'verify_email', $activationKey) +{ + global $hesk_settings, $ticket; + + if (defined('HESK_DEMO')) + { + return true; + } + + // Format email subject and message + $subject = hesk_getEmailSubject($email_template, $ticket); + $message = hesk_getEmailMessage($email_template, $ticket); + $activationUrl = $hesk_settings['hesk_url'] . '/verifyemail.php?key=%%ACTIVATIONKEY%%'; + $message = str_replace('%%VERIFYURL%%', $activationUrl, $message); + $message = str_replace('%%ACTIVATIONKEY%%', $activationKey, $message); + + hesk_mail($ticket['email'], $subject, $message); +} + function hesk_notifyCustomer($email_template = 'new_ticket') { @@ -225,6 +244,9 @@ function hesk_validEmails() // --> Ticket closed 'ticket_closed' => $hesklang['ticket_closed'], + // --> Verify email + 'verify_email' => $hesklang['verify_email'], + /*** Emails sent to STAFF ***/ @@ -246,6 +268,9 @@ function hesk_validEmails() // --> New note by someone to a ticket assigned to you 'new_note' => $hesklang['new_note'], + // --> Assigned ticket reopened + 'ticket_reopen_assigned' => $hesklang['ticket_reopen_assigned'], + ); } // END hesk_validEmails() diff --git a/inc/header.inc.php b/inc/header.inc.php index 70375a1a..6f440217 100644 --- a/inc/header.inc.php +++ b/inc/header.inc.php @@ -47,6 +47,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); + @@ -60,6 +61,8 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); + + > + + + + diff --git a/inc/headerAdmin.inc.php b/inc/headerAdmin.inc.php index 63e6bfe9..1088af73 100644 --- a/inc/headerAdmin.inc.php +++ b/inc/headerAdmin.inc.php @@ -47,6 +47,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); + @@ -61,6 +62,7 @@ require(HESK_PATH . 'modsForHesk_settings.inc.php'); + 'CRITICAL', - 1 => 'HIGH', - 2 => 'MEDIUM', - 3 => 'LOW', - ); + $priority = array( + 0 => 'CRITICAL', + 1 => 'HIGH', + 2 => 'MEDIUM', + 3 => 'LOW', + ); } if ( ! isset($what) ) { - $what = 'trackid'; + $what = 'trackid'; } if ( ! isset($date_input) ) { - $date_input = ''; + $date_input = ''; } /* Can view tickets that are unassigned or assigned to others? */ @@ -73,22 +73,22 @@ $can_view_unassigned = hesk_checkPermission('can_view_unassigned',0); $category_options = ''; if ( isset($hesk_settings['categories']) && count($hesk_settings['categories']) ) { - foreach ($hesk_settings['categories'] as $row['id'] => $row['name']) - { - $row['name'] = (strlen($row['name']) > 30) ? substr($row['name'],0,30) . '...' : $row['name']; - $selected = ($row['id'] == $category) ? 'selected="selected"' : ''; - $category_options .= ''; - } + foreach ($hesk_settings['categories'] as $row['id'] => $row['name']) + { + $row['name'] = (strlen($row['name']) > 30) ? substr($row['name'],0,30) . '...' : $row['name']; + $selected = ($row['id'] == $category) ? 'selected="selected"' : ''; + $category_options .= ''; + } } else { - $res2 = hesk_dbQuery('SELECT `id`, `name` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'categories` WHERE ' . hesk_myCategories('id') . ' ORDER BY `cat_order` ASC'); - while ($row=hesk_dbFetchAssoc($res2)) - { - $row['name'] = (strlen($row['name']) > 30) ? substr($row['name'],0,30) . '...' : $row['name']; - $selected = ($row['id'] == $category) ? 'selected="selected"' : ''; - $category_options .= ''; - } + $res2 = hesk_dbQuery('SELECT `id`, `name` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'categories` WHERE ' . hesk_myCategories('id') . ' ORDER BY `cat_order` ASC'); + while ($row=hesk_dbFetchAssoc($res2)) + { + $row['name'] = (strlen($row['name']) > 30) ? substr($row['name'],0,30) . '...' : $row['name']; + $selected = ($row['id'] == $category) ? 'selected="selected"' : ''; + $category_options .= ''; + } } $more = empty($_GET['more']) ? 0 : 1; @@ -98,337 +98,342 @@ $more2 = empty($_GET['more2']) ? 0 : 1; ?> +
+ + + | +
- Database Settings
+ ';
+ echo 'Double-check all the information below. Contact your hosting company for the correct information to use! MySQL said: '.$mysql_log.'', 'Database connection failed'; + echo ''; + } + elseif ($problem == 2) + { + echo ' ';
+ echo 'Database tables already exist! ';
+ }
+ elseif ($problem == 3)
+ {
+ echo '+ HESK database tables with '.$hesk_settings['db_pfix'].' prefix already exist in this database! + To upgrade an existing HESK installation select Update existing install instead. + To install a new copy of HESK in use a unique table prefix.'; + echo ' ';
+ echo 'Old database tables not found! ';
+ }
+ elseif ($problem == 4)
+ {
+ echo '+ HESK database tables have not been found in this database! + To install HESK use the New install option instead.'; + echo ' ';
+ echo 'Version '.HESK_NEW_VERSION.' tables already exist! ';
+ }
+ ?>
+ Your database seems to be compatible with HESK version '.HESK_NEW_VERSION.' + To install a new copy of HESK use the New install option instead.'; + echo '
diff --git a/install/updateModsForHesk.php b/install/updateModsForHesk.php
index 3503a673..7c05ad18 100644
--- a/install/updateModsForHesk.php
+++ b/install/updateModsForHesk.php
@@ -6,12 +6,13 @@ require(HESK_PATH . 'hesk_settings.inc.php');
?>
- Mods for HESK 1.6.0 Install / Upgrade+Mods for HESK 1.7.0 Install / UpgradeSelect your current Mods for HESK version number to upgrade.
Please verify the database information below. Additionally, ensure that the database user has CREATE and ALTER permissions. +Please verify the database information below. Additionally, ensure that the database user has CREATE and ALTER permissions. Database Host: Database Name: Database User: diff --git a/install/updateTo1-6-0.php b/install/updateTo1-6-0.php index bf1d0184..616ebb48 100644 --- a/install/updateTo1-6-0.php +++ b/install/updateTo1-6-0.php @@ -13,4 +13,4 @@ hesk_dbQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."attachmen hesk_dbQuery("CREATE TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` (`Key` NVARCHAR(200) NOT NULL, `Value` NVARCHAR(200) NOT NULL)"); hesk_dbQuery("INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` (`Key`, `Value`) VALUES ('modsForHeskVersion', '1.6.0')"); -header('Location: update-to1-6-1.php'); \ No newline at end of file +header('Location: updateTo1-6-1.php'); \ No newline at end of file diff --git a/install/updateTo1-6-1.php b/install/updateTo1-6-1.php index 359edddf..977540ba 100644 --- a/install/updateTo1-6-1.php +++ b/install/updateTo1-6-1.php @@ -5,7 +5,5 @@ require(HESK_PATH . 'install/install_functions.inc.php'); require(HESK_PATH . 'hesk_settings.inc.php'); hesk_dbConnect(); hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '1.6.1' WHERE `Key` = 'modsForHeskVersion'"); -?> -Installation / Update complete!-Please delete the install folder for security reasons, and then proceed back to the Help Desk \ No newline at end of file +header('Location: updateTo1-7-0.php'); \ No newline at end of file diff --git a/install/updateTo1-7-0.php b/install/updateTo1-7-0.php new file mode 100644 index 00000000..1808270f --- /dev/null +++ b/install/updateTo1-7-0.php @@ -0,0 +1,105 @@ +Failure! +An issue occurred when trying to update the modsForHesk_settings.inc.php file. ++ Add the following lines to your modsForHesk_settings.inc.php file: ++ //-- Set this to 1 to enable custom field names as keys
+ $modsForHesk_settings[\'custom_field_setting\'] = 0; + + //-- Set this to 1 to enable email verification for new customers
+ $modsForHesk_settings[\'customer_email_verification_required\'] = 0;
+
+ + Now you can delete the install folder for security reasons, and then proceed back to the Help Desk '; + +} + +if ($updateSuccess) { +?> + +Installation / Update complete!+Please delete the install folder for security reasons, and then proceed back to the Help Desk + + \ No newline at end of file diff --git a/js/bootstrap-datepicker.js b/js/bootstrap-datepicker.js new file mode 100755 index 00000000..5db96af2 --- /dev/null +++ b/js/bootstrap-datepicker.js @@ -0,0 +1,1681 @@ +/* ========================================================= + * bootstrap-datepicker.js + * Repo: https://github.com/eternicode/bootstrap-datepicker/ + * Demo: http://eternicode.github.io/bootstrap-datepicker/ + * Docs: http://bootstrap-datepicker.readthedocs.org/ + * Forked from http://www.eyecon.ro/bootstrap-datepicker + * ========================================================= + * Started by Stefan Petre; improvements by Andrew Rowls + contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + +(function($, undefined){ + + var $window = $(window); + + function UTCDate(){ + return new Date(Date.UTC.apply(Date, arguments)); + } + function UTCToday(){ + var today = new Date(); + return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); + } + function alias(method){ + return function(){ + return this[method].apply(this, arguments); + }; + } + + var DateArray = (function(){ + var extras = { + get: function(i){ + return this.slice(i)[0]; + }, + contains: function(d){ + // Array.indexOf is not cross-browser; + // $.inArray doesn't work with Dates + var val = d && d.valueOf(); + for (var i=0, l=this.length; i < l; i++) + if (this[i].valueOf() === val) + return i; + return -1; + }, + remove: function(i){ + this.splice(i,1); + }, + replace: function(new_array){ + if (!new_array) + return; + if (!$.isArray(new_array)) + new_array = [new_array]; + this.clear(); + this.push.apply(this, new_array); + }, + clear: function(){ + this.length = 0; + }, + copy: function(){ + var a = new DateArray(); + a.replace(this); + return a; + } + }; + + return function(){ + var a = []; + a.push.apply(a, arguments); + $.extend(a, extras); + return a; + }; + })(); + + + // Picker object + + var Datepicker = function(element, options){ + this.dates = new DateArray(); + this.viewDate = UTCToday(); + this.focusDate = null; + + this._process_options(options); + + this.element = $(element); + this.isInline = false; + this.isInput = this.element.is('input'); + this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false; + this.hasInput = this.component && this.element.find('input').length; + if (this.component && this.component.length === 0) + this.component = false; + + this.picker = $(DPGlobal.template); + this._buildEvents(); + this._attachEvents(); + + if (this.isInline){ + this.picker.addClass('datepicker-inline').appendTo(this.element); + } + else { + this.picker.addClass('datepicker-dropdown dropdown-menu'); + } + + if (this.o.rtl){ + this.picker.addClass('datepicker-rtl'); + } + + this.viewMode = this.o.startView; + + if (this.o.calendarWeeks) + this.picker.find('tfoot th.today, tfoot th.clear') + .attr('colspan', function(i, val){ + return parseInt(val) + 1; + }); + + this._allow_update = false; + + this.setStartDate(this._o.startDate); + this.setEndDate(this._o.endDate); + this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); + + this.fillDow(); + this.fillMonths(); + + this._allow_update = true; + + this.update(); + this.showMode(); + + if (this.isInline){ + this.show(); + } + }; + + Datepicker.prototype = { + constructor: Datepicker, + + _process_options: function(opts){ + // Store raw options for reference + this._o = $.extend({}, this._o, opts); + // Processed options + var o = this.o = $.extend({}, this._o); + + // Check if "de-DE" style date is available, if not language should + // fallback to 2 letter code eg "de" + var lang = o.language; + if (!dates[lang]){ + lang = lang.split('-')[0]; + if (!dates[lang]) + lang = defaults.language; + } + o.language = lang; + + switch (o.startView){ + case 2: + case 'decade': + o.startView = 2; + break; + case 1: + case 'year': + o.startView = 1; + break; + default: + o.startView = 0; + } + + switch (o.minViewMode){ + case 1: + case 'months': + o.minViewMode = 1; + break; + case 2: + case 'years': + o.minViewMode = 2; + break; + default: + o.minViewMode = 0; + } + + o.startView = Math.max(o.startView, o.minViewMode); + + // true, false, or Number > 0 + if (o.multidate !== true){ + o.multidate = Number(o.multidate) || false; + if (o.multidate !== false) + o.multidate = Math.max(0, o.multidate); + else + o.multidate = 1; + } + o.multidateSeparator = String(o.multidateSeparator); + + o.weekStart %= 7; + o.weekEnd = ((o.weekStart + 6) % 7); + + var format = DPGlobal.parseFormat(o.format); + if (o.startDate !== -Infinity){ + if (!!o.startDate){ + if (o.startDate instanceof Date) + o.startDate = this._local_to_utc(this._zero_time(o.startDate)); + else + o.startDate = DPGlobal.parseDate(o.startDate, format, o.language); + } + else { + o.startDate = -Infinity; + } + } + if (o.endDate !== Infinity){ + if (!!o.endDate){ + if (o.endDate instanceof Date) + o.endDate = this._local_to_utc(this._zero_time(o.endDate)); + else + o.endDate = DPGlobal.parseDate(o.endDate, format, o.language); + } + else { + o.endDate = Infinity; + } + } + + o.daysOfWeekDisabled = o.daysOfWeekDisabled||[]; + if (!$.isArray(o.daysOfWeekDisabled)) + o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/); + o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){ + return parseInt(d, 10); + }); + + var plc = String(o.orientation).toLowerCase().split(/\s+/g), + _plc = o.orientation.toLowerCase(); + plc = $.grep(plc, function(word){ + return (/^auto|left|right|top|bottom$/).test(word); + }); + o.orientation = {x: 'auto', y: 'auto'}; + if (!_plc || _plc === 'auto') + ; // no action + else if (plc.length === 1){ + switch (plc[0]){ + case 'top': + case 'bottom': + o.orientation.y = plc[0]; + break; + case 'left': + case 'right': + o.orientation.x = plc[0]; + break; + } + } + else { + _plc = $.grep(plc, function(word){ + return (/^left|right$/).test(word); + }); + o.orientation.x = _plc[0] || 'auto'; + + _plc = $.grep(plc, function(word){ + return (/^top|bottom$/).test(word); + }); + o.orientation.y = _plc[0] || 'auto'; + } + }, + _events: [], + _secondaryEvents: [], + _applyEvents: function(evs){ + for (var i=0, el, ch, ev; i < evs.length; i++){ + el = evs[i][0]; + if (evs[i].length === 2){ + ch = undefined; + ev = evs[i][1]; + } + else if (evs[i].length === 3){ + ch = evs[i][1]; + ev = evs[i][2]; + } + el.on(ev, ch); + } + }, + _unapplyEvents: function(evs){ + for (var i=0, el, ev, ch; i < evs.length; i++){ + el = evs[i][0]; + if (evs[i].length === 2){ + ch = undefined; + ev = evs[i][1]; + } + else if (evs[i].length === 3){ + ch = evs[i][1]; + ev = evs[i][2]; + } + el.off(ev, ch); + } + }, + _buildEvents: function(){ + if (this.isInput){ // single input + this._events = [ + [this.element, { + focus: $.proxy(this.show, this), + keyup: $.proxy(function(e){ + if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) + this.update(); + }, this), + keydown: $.proxy(this.keydown, this) + }] + ]; + } + else if (this.component && this.hasInput){ // component: input + button + this._events = [ + // For components that are not readonly, allow keyboard nav + [this.element.find('input'), { + focus: $.proxy(this.show, this), + keyup: $.proxy(function(e){ + if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) + this.update(); + }, this), + keydown: $.proxy(this.keydown, this) + }], + [this.component, { + click: $.proxy(this.show, this) + }] + ]; + } + else if (this.element.is('div')){ // inline datepicker + this.isInline = true; + } + else { + this._events = [ + [this.element, { + click: $.proxy(this.show, this) + }] + ]; + } + this._events.push( + // Component: listen for blur on element descendants + [this.element, '*', { + blur: $.proxy(function(e){ + this._focused_from = e.target; + }, this) + }], + // Input: listen for blur on element + [this.element, { + blur: $.proxy(function(e){ + this._focused_from = e.target; + }, this) + }] + ); + + this._secondaryEvents = [ + [this.picker, { + click: $.proxy(this.click, this) + }], + [$(window), { + resize: $.proxy(this.place, this) + }], + [$(document), { + 'mousedown touchstart': $.proxy(function(e){ + // Clicked outside the datepicker, hide it + if (!( + this.element.is(e.target) || + this.element.find(e.target).length || + this.picker.is(e.target) || + this.picker.find(e.target).length + )){ + this.hide(); + } + }, this) + }] + ]; + }, + _attachEvents: function(){ + this._detachEvents(); + this._applyEvents(this._events); + }, + _detachEvents: function(){ + this._unapplyEvents(this._events); + }, + _attachSecondaryEvents: function(){ + this._detachSecondaryEvents(); + this._applyEvents(this._secondaryEvents); + }, + _detachSecondaryEvents: function(){ + this._unapplyEvents(this._secondaryEvents); + }, + _trigger: function(event, altdate){ + var date = altdate || this.dates.get(-1), + local_date = this._utc_to_local(date); + + this.element.trigger({ + type: event, + date: local_date, + dates: $.map(this.dates, this._utc_to_local), + format: $.proxy(function(ix, format){ + if (arguments.length === 0){ + ix = this.dates.length - 1; + format = this.o.format; + } + else if (typeof ix === 'string'){ + format = ix; + ix = this.dates.length - 1; + } + format = format || this.o.format; + var date = this.dates.get(ix); + return DPGlobal.formatDate(date, format, this.o.language); + }, this) + }); + }, + + show: function(){ + if (!this.isInline) + this.picker.appendTo('body'); + this.picker.show(); + this.place(); + this._attachSecondaryEvents(); + this._trigger('show'); + }, + + hide: function(){ + if (this.isInline) + return; + if (!this.picker.is(':visible')) + return; + this.focusDate = null; + this.picker.hide().detach(); + this._detachSecondaryEvents(); + this.viewMode = this.o.startView; + this.showMode(); + + if ( + this.o.forceParse && + ( + this.isInput && this.element.val() || + this.hasInput && this.element.find('input').val() + ) + ) + this.setValue(); + this._trigger('hide'); + }, + + remove: function(){ + this.hide(); + this._detachEvents(); + this._detachSecondaryEvents(); + this.picker.remove(); + delete this.element.data().datepicker; + if (!this.isInput){ + delete this.element.data().date; + } + }, + + _utc_to_local: function(utc){ + return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000)); + }, + _local_to_utc: function(local){ + return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000)); + }, + _zero_time: function(local){ + return local && new Date(local.getFullYear(), local.getMonth(), local.getDate()); + }, + _zero_utc_time: function(utc){ + return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate())); + }, + + getDates: function(){ + return $.map(this.dates, this._utc_to_local); + }, + + getUTCDates: function(){ + return $.map(this.dates, function(d){ + return new Date(d); + }); + }, + + getDate: function(){ + return this._utc_to_local(this.getUTCDate()); + }, + + getUTCDate: function(){ + return new Date(this.dates.get(-1)); + }, + + setDates: function(){ + var args = $.isArray(arguments[0]) ? arguments[0] : arguments; + this.update.apply(this, args); + this._trigger('changeDate'); + this.setValue(); + }, + + setUTCDates: function(){ + var args = $.isArray(arguments[0]) ? arguments[0] : arguments; + this.update.apply(this, $.map(args, this._utc_to_local)); + this._trigger('changeDate'); + this.setValue(); + }, + + setDate: alias('setDates'), + setUTCDate: alias('setUTCDates'), + + setValue: function(){ + var formatted = this.getFormattedDate(); + if (!this.isInput){ + if (this.component){ + this.element.find('input').val(formatted).change(); + } + } + else { + this.element.val(formatted).change(); + } + }, + + getFormattedDate: function(format){ + if (format === undefined) + format = this.o.format; + + var lang = this.o.language; + return $.map(this.dates, function(d){ + return DPGlobal.formatDate(d, format, lang); + }).join(this.o.multidateSeparator); + }, + + setStartDate: function(startDate){ + this._process_options({startDate: startDate}); + this.update(); + this.updateNavArrows(); + }, + + setEndDate: function(endDate){ + this._process_options({endDate: endDate}); + this.update(); + this.updateNavArrows(); + }, + + setDaysOfWeekDisabled: function(daysOfWeekDisabled){ + this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); + this.update(); + this.updateNavArrows(); + }, + + place: function(){ + if (this.isInline) + return; + var calendarWidth = this.picker.outerWidth(), + calendarHeight = this.picker.outerHeight(), + visualPadding = 10, + windowWidth = $window.width(), + windowHeight = $window.height(), + scrollTop = $window.scrollTop(); + + var parentsZindex = []; + this.element.parents().each(function() { + var itemZIndex = $(this).css('z-index'); + if ( itemZIndex !== 'auto' && itemZIndex !== 0 ) parentsZindex.push( parseInt( itemZIndex ) ); + }); + var zIndex = Math.max.apply( Math, parentsZindex ) + 10; + var offset = this.component ? this.component.parent().offset() : this.element.offset(); + var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); + var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); + var left = offset.left, + top = offset.top; + + this.picker.removeClass( + 'datepicker-orient-top datepicker-orient-bottom '+ + 'datepicker-orient-right datepicker-orient-left' + ); + + if (this.o.orientation.x !== 'auto'){ + this.picker.addClass('datepicker-orient-' + this.o.orientation.x); + if (this.o.orientation.x === 'right') + left -= calendarWidth - width; + } + // auto x orientation is best-placement: if it crosses a window + // edge, fudge it sideways + else { + // Default to left + this.picker.addClass('datepicker-orient-left'); + if (offset.left < 0) + left -= offset.left - visualPadding; + else if (offset.left + calendarWidth > windowWidth) + left = windowWidth - calendarWidth - visualPadding; + } + + // auto y orientation is best-situation: top or bottom, no fudging, + // decision based on which shows more of the calendar + var yorient = this.o.orientation.y, + top_overflow, bottom_overflow; + if (yorient === 'auto'){ + top_overflow = -scrollTop + offset.top - calendarHeight; + bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight); + if (Math.max(top_overflow, bottom_overflow) === bottom_overflow) + yorient = 'top'; + else + yorient = 'bottom'; + } + this.picker.addClass('datepicker-orient-' + yorient); + if (yorient === 'top') + top += height; + else + top -= calendarHeight + parseInt(this.picker.css('padding-top')); + + this.picker.css({ + top: top, + left: left, + zIndex: zIndex + }); + }, + + _allow_update: true, + update: function(){ + if (!this._allow_update) + return; + + var oldDates = this.dates.copy(), + dates = [], + fromArgs = false; + if (arguments.length){ + $.each(arguments, $.proxy(function(i, date){ + if (date instanceof Date) + date = this._local_to_utc(date); + dates.push(date); + }, this)); + fromArgs = true; + } + else { + dates = this.isInput + ? this.element.val() + : this.element.data('date') || this.element.find('input').val(); + if (dates && this.o.multidate) + dates = dates.split(this.o.multidateSeparator); + else + dates = [dates]; + delete this.element.data().date; + } + + dates = $.map(dates, $.proxy(function(date){ + return DPGlobal.parseDate(date, this.o.format, this.o.language); + }, this)); + dates = $.grep(dates, $.proxy(function(date){ + return ( + date < this.o.startDate || + date > this.o.endDate || + !date + ); + }, this), true); + this.dates.replace(dates); + + if (this.dates.length) + this.viewDate = new Date(this.dates.get(-1)); + else if (this.viewDate < this.o.startDate) + this.viewDate = new Date(this.o.startDate); + else if (this.viewDate > this.o.endDate) + this.viewDate = new Date(this.o.endDate); + + if (fromArgs){ + // setting date by clicking + this.setValue(); + } + else if (dates.length){ + // setting date by typing + if (String(oldDates) !== String(this.dates)) + this._trigger('changeDate'); + } + if (!this.dates.length && oldDates.length) + this._trigger('clearDate'); + + this.fill(); + }, + + fillDow: function(){ + var dowCnt = this.o.weekStart, + html = ' | ';
+ html += cell;
+ this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
+ }
+ while (dowCnt < this.o.weekStart + 7){
+ html += ''+dates[this.o.language].daysMin[(dowCnt++)%7]+' | ';
+ }
+ html += ''+ calWeek +' | ');
+
+ }
+ }
+ clsName = this.getClassNames(prevMonth);
+ clsName.push('day');
+
+ if (this.o.beforeShowDay !== $.noop){
+ var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
+ if (before === undefined)
+ before = {};
+ else if (typeof(before) === 'boolean')
+ before = {enabled: before};
+ else if (typeof(before) === 'string')
+ before = {classes: before};
+ if (before.enabled === false)
+ clsName.push('disabled');
+ if (before.classes)
+ clsName = clsName.concat(before.classes.split(/\s+/));
+ if (before.tooltip)
+ tooltip = before.tooltip;
+ }
+
+ clsName = $.unique(clsName);
+ html.push(''+prevMonth.getUTCDate() + ' | ');
+ tooltip = null;
+ if (prevMonth.getUTCDay() === this.o.weekEnd){
+ html.push('« | '+
+ ''+
+ ' | » | '+
+ ''+
+ ' | '+
+ ' | '+
+ ' ';
+
+ $.fn.datepicker.DPGlobal = DPGlobal;
+
+
+ /* DATEPICKER NO CONFLICT
+ * =================== */
+
+ $.fn.datepicker.noConflict = function(){
+ $.fn.datepicker = old;
+ return this;
+ };
+
+
+ /* DATEPICKER DATA-API
+ * ================== */
+
+ $(document).on(
+ 'focus.datepicker.data-api click.datepicker.data-api',
+ '[data-provide="datepicker"]',
+ function(e){
+ var $this = $(this);
+ if ($this.data('datepicker'))
+ return;
+ e.preventDefault();
+ // component click requires us to explicitly show it
+ $this.datepicker('show');
+ }
+ );
+ $(function(){
+ $('[data-provide="datepicker-inline"]').datepicker();
+ });
+
+}(window.jQuery));
diff --git a/js/modsForHesk-javascript.js b/js/modsForHesk-javascript.js
index f8100465..5383ad72 100644
--- a/js/modsForHesk-javascript.js
+++ b/js/modsForHesk-javascript.js
@@ -4,12 +4,39 @@ var loadJquery = function()
//-- Activate tooltips
$('[data-toggle="tooltip"]').tooltip();
- //-- Active popovers
+ //-- Activate popovers
$('[data-toggle="popover"]').popover({
- trigger: 'hover'
- })
+ trigger: 'hover',
+ container: 'body'
+ });
+
+ //-- Activate HTML popovers
+ $('[data-toggle="htmlpopover"]').popover({
+ trigger: 'hover',
+ container: 'body',
+ html: 'true'
+ });
+
+ //-- Activate jQuery's date picker
+ $(function() {
+ $('.datepicker').datepicker({
+ todayBtn: "linked",
+ clearBtn: true,
+ autoclose: true,
+ todayHighlight: true,
+ format: "yyyy-mm-dd"
+ });
+ });
};
+function selectAll(id) {
+ $('#' + id + ' option').prop('selected', true);
+}
+
+function deselectAll(id) {
+ $('#' + id + ' option').prop('selected', false);
+}
+
function toggleRow(id) {
if ($('#' + id).hasClass('danger'))
{
diff --git a/language/en/emails/ticket_reopen_assigned.txt b/language/en/emails/ticket_reopen_assigned.txt
new file mode 100644
index 00000000..ace2d404
--- /dev/null
+++ b/language/en/emails/ticket_reopen_assigned.txt
@@ -0,0 +1,16 @@
+Hello,
+
+A support ticket assigned to you has been re-opened.
+
+%%NAME%% has just re-opened the ticket "%%SUBJECT%%".
+
+Tracking ID: %%TRACK_ID%%
+
+You can manage this ticket here:
+%%TRACK_URL%%
+
+
+Regards,
+
+%%SITE_TITLE%%
+%%SITE_URL%%
\ No newline at end of file
diff --git a/language/en/emails/verify_email.txt b/language/en/emails/verify_email.txt
new file mode 100644
index 00000000..fa573f6f
--- /dev/null
+++ b/language/en/emails/verify_email.txt
@@ -0,0 +1,10 @@
+Dear %%NAME%%,
+
+Your email needs to be verified before your ticket can be submitted. Please click the link below to verify your email.
+
+%%VERIFYURL%%
+
+Sincerely,
+
+%%SITE_TITLE%%
+%%SITE_URL%%
\ No newline at end of file
diff --git a/language/en/text.php b/language/en/text.php
index f4c4174a..ba17d865 100644
--- a/language/en/text.php
+++ b/language/en/text.php
@@ -21,6 +21,34 @@ $hesklang['_COLLATE']='utf8_unicode_ci';
// This is the email break line that will be used in email piping
$hesklang['EMAIL_HR']='------ Reply above this line ------';
+// ADDED OR MODIFIED IN Mods For HESK 1.7.0
+$hesklang['date_custom_field'] = 'Date';
+$hesklang['date_custom_field_text'] = 'No options for this custom field type.';
+$hesklang['multiple_select_custom_field'] = 'Multiple Select box';
+$hesklang['multiple_select_custom_field_text'] = 'Options for this multi-select box, enter one option per line (each line will be a choice your customers can choose from). You need to enter at least two options!';
+$hesklang['date_format'] = 'Date must be in YYYY-MM-DD format.';
+$hesklang['custom_field_setting'] = 'Multilanguage support';
+$hesklang['custom_field_setting_help'] = 'Enabling this setting will use the name of the custom field as the language
+ file\'s key, rather than the direct name itself. This allows the custom field to be translated into different languages.';
+$hesklang['enable_custom_field_language'] = 'Enable multilanguage support';
+$hesklang['custom_language_key'] = 'Field language file key';
+$hesklang['ticket_reopen_assigned'] = '[#%%TRACK_ID%%] Assigned ticket reopened';
+$hesklang['verify_email'] = 'Verify Email';
+$hesklang['email_verified'] = 'The email address %s has been verified. Additionally, the following tickets have been created:'; //%s: email address
+$hesklang['verify_no_records'] = 'No records were found for this activation key. Has this activation key already been used?';
+$hesklang['activation_key'] = 'Activation Key';
+$hesklang['no_tickets_created'] = 'No tickets created';
+$hesklang['customer_email_verification'] = 'Customer Email Verifications';
+$hesklang['customer_email_verification_help'] = 'Require customers to verify their email address via email. Once their
+ address has been verified, it does not need to be re-verified in the future. '+
+ ' '+
+ ''+
+ ' '+
+ ''+
+ ' '+
+ 'NOTE: Enabling this will disable the + ability for the customer to provide multiple emails, as HESK will be unable to determine which email needs to be verified.'; +$hesklang['require_customer_validate_email'] = 'Require customers to verify email'; +$hesklang['multi_eml_disabled'] = 'This feature has been disabled because this help desk has been configured to require + customers to verify their email address'; +$hesklang['feature_disabled'] = 'Feature Disabled'; +$hesklang['verify_your_email'] = 'Your ticket has been created; however your email needs to be verified before your ticket can be addressed. An email has been sent to the email provided for verification.'; +$hesklang['installation_information'] = 'Installation Information'; + // ADDED OR MODIFIED IN Mods For HESK 1.6.0 $hesklang['ticket_closed'] = '[#%%TRACK_ID%%] Ticket closed/resolved'; $hesklang['ticket_reopen'] = '[#%%TRACK_ID%%] Ticket reopened'; diff --git a/modsForHesk_settings.inc.php b/modsForHesk_settings.inc.php index 2d9a5780..3335dc4e 100644 --- a/modsForHesk_settings.inc.php +++ b/modsForHesk_settings.inc.php @@ -17,4 +17,10 @@ $modsForHesk_settings['questionMarkColor'] = '#000000'; $modsForHesk_settings['rtl'] = 0; //-- Set this to 1 to show icons next to navigation menu items -$modsForHesk_settings['show_icons'] = 0; \ No newline at end of file +$modsForHesk_settings['show_icons'] = 0; + +//-- Set this to 1 to enable custom field names as keys +$modsForHesk_settings['custom_field_setting'] = 0; + +//-- Set this to 1 to enable email verification for new customers +$modsForHesk_settings['customer_email_verification_required'] = 0;$modsForHesk_settings['show_icons'] = 0; \ No newline at end of file diff --git a/print.php b/print.php index 5ae2ebf7..4b0fb8f8 100644 --- a/print.php +++ b/print.php @@ -206,8 +206,13 @@ $num_cols = 0; echo ' ' . - $hesklang['ticket_submitted_success'] . ': ' . $ticket['trackid'] . ' + $hesklang['ticket_submitted'] . ' ' . + $hesklang['ticket_submitted_success'] . ': ' . $ticket['trackid'] . ' ' . $hesklang['view_your_ticket'] . '' - ); + ); + } else + { + hesk_show_notice($hesklang['verify_your_email'].' '.$hesklang['check_spambox']); + } // Any other messages to display? hesk_handle_messages(); diff --git a/ticket.php b/ticket.php index fe6cc0a5..18c4c008 100644 --- a/ticket.php +++ b/ticket.php @@ -212,16 +212,6 @@ require_once(HESK_PATH . 'inc/header.inc.php');
-
-
-
-
-
-
-
-
-
- '.$v['name'].': '.$ticket[$k].' '; + if ($modsForHesk_settings['custom_field_setting']) + { + $v['name'] = $hesklang[$v['name']]; + } + + echo ''.$v['name'].': '; + if ($v['type'] == 'date' && !empty($ticket[$k])) + { + $dt = date('Y-m-d h:i:s', $ticket[$k]); + echo hesk_dateToString($dt, 0); + } else + { + echo $ticket[$k]; + } + echo ' '; } } ?> @@ -358,8 +361,21 @@ require_once(HESK_PATH . 'inc/header.inc.php'); { if ($v['use'] && $v['place']) { - echo ' -'.$v['name'].': '.$ticket[$k].' '; + if ($modsForHesk_settings['custom_field_setting']) + { + $v['name'] = $hesklang[$v['name']]; + } + + echo ''.$v['name'].': '; + if ($v['type'] == 'date' && !empty($ticket[$k])) + { + $dt = date('Y-m-d h:i:s', $ticket[$k]); + echo hesk_dateToString($dt, 0); + } else + { + echo $ticket[$k]; + } + echo ' '; } } /* Attachments */ diff --git a/verifyemail.php b/verifyemail.php new file mode 100644 index 00000000..a77999e7 --- /dev/null +++ b/verifyemail.php @@ -0,0 +1,128 @@ + + +
+
+
\ No newline at end of file
+
+
+
+ fetch_assoc())
+ {
+ $email = $result['Email'];
+ $ticketRs = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets`
+ WHERE `email` = '".hesk_dbEscape($result['Email'])."'");
+ while ($innerResult = $ticketRs->fetch_assoc())
+ {
+ $ticket = hesk_newTicket($innerResult);
+ // Notify the customer
+ hesk_notifyCustomer();
+
+ // Need to notify staff?
+ // --> From autoassign?
+ $getOwnerRs = hesk_dbQuery("SELECT * FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."users` WHERE ID = ".hesk_dbEscape($ticket['owner']));
+ $autoassign_owner = $getOwnerRs->fetch_assoc();
+ if ($ticket['owner'] && $autoassign_owner['notify_assigned'])
+ {
+ hesk_notifyAssignedStaff($autoassign_owner, 'ticket_assigned_to_you');
+ }
+ // --> No autoassign, find and notify appropriate staff
+ elseif ( ! $ticket['owner'] )
+ {
+ hesk_notifyStaff('new_ticket_staff', " `notify_new_unassigned` = '1' ");
+ }
+
+ array_push($submittedTickets, $innerResult['trackid']);
+ hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets`
+ WHERE `id` = ".$innerResult['id']);
+ }
+
+ //Add email address to the verified emails table
+ hesk_dbQuery('INSERT INTO `'.hesk_dbEscape($hesk_settings['db_pfix']).'verified_emails` (`Email`) VALUES (\''.hesk_dbEscape($email).'\')');
+ }
+ hesk_dbQuery("DELETE FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."pending_verification_emails`
+ WHERE `ActivationKey` = '".hesk_dbEscape($key)."'");
+
+ //-- was there an email recorded for the key?
+ if (!empty($email))
+ {
+ $showForm = false;
+ ?>
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ |