diff --git a/.gitignore b/.gitignore index f5c8800f..39da1146 100644 --- a/.gitignore +++ b/.gitignore @@ -257,6 +257,8 @@ language/en/emails/new_ticket_staff.txt language/en/emails/ticket_assigned_to_you.txt language/en/index.htm language/index.htm +language/* +!language/en print_sec_img.php rate.php readme.html @@ -270,4 +272,4 @@ img/ico_tools.png inc/recaptcha/recaptchalib_v2.php ip_whois.php language/en/emails/reset_password.txt -language/en/help_files/ticket_list.html \ No newline at end of file +language/en/help_files/ticket_list.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9361de11..7588eb86 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,8 +3,8 @@ So you want to contribute to Mods for HESK? Awesome! However, there are a few gu ## Submitting an issue If all you are doing is submitting an issue, please check if your "issue" qualifies as a GitHub issue: - - **Feature Requests:** Feature requests are now being recorded at the Mods for HESK [UserVoice page](https://mods-for-hesk.uservoice.com/forums/254758-general). Please do not open these types of issues on GitHub. - - **Translations:** Translations are now being recorded at the official Mods for HESK [translations topic](http://developers.phpjunkyard.com/viewtopic.php?f=19&t=5217). Please do not open these types of issues on GitHub. + - **Feature Requests:** Feature requests are now being recorded at the Mods for HESK [UserVoice page](https://mods-for-hesk.uservoice.com/forums/254758-general). Please do not open these types of issues on GitHub. Issues opened that are "feature requests" will be closed. + - **Translations:** Translations are now being recorded at the official Mods for HESK [translations topic](http://developers.phpjunkyard.com/viewtopic.php?f=19&t=5217). Please do not open these types of issues on GitHub. Issues opened that pertain to submitting new translations will be closed. - **Bugs:** Yes, please open these types of issues here. :grinning: ## Getting Started @@ -25,4 +25,4 @@ If you have already completed any of these steps in the past (such as creating a - Push your changes to a topic branch in your fork of the repository - Submit a pull request to the official Mods for HESK repository (mkoch227/Mods-for-HESK) - The owner of Mods for HESK will then inspect and test the code in the pull request. Feedback will be given via GitHub comments. - - The owner of Mods for HESK expects responses within two weeks of the original comment. If there is no feedback within that time range, the pull request will be considered abandoned and subsequently will be closed. \ No newline at end of file + - The owner of Mods for HESK expects responses within two weeks of the original comment. If there is no feedback within that time range, the pull request will be considered abandoned and subsequently will be closed. diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..62ba2712 --- /dev/null +++ b/LICENSE @@ -0,0 +1,427 @@ +NOTE: This license only applies to Mods for HESK. It does not apply to HESK. + +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/README.md b/README.md index 428c5f5e..a49f6ec7 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ -## [Mods for HESK](http://mods-for-hesk.mkochcs.com) v2.0.1 +## [Mods for HESK](http://mods-for-hesk.mkochcs.com) [![Current Release](https://img.shields.io/github/release/mkoch227/Mods-for-HESK.svg)](https://www.github.com/mkoch227/Mods-for-HESK/releases) [![Project Status](http://stillmaintained.com/mkoch227/Mods-for-HESK.png)](https://www.github.com/mkoch227/Mods-for-HESK) [![Stories in Ready](https://badge.waffle.io/mkoch227/Mods-For-Hesk.png?label=waffle:ready&title=Ready)](https://waffle.io/mkoch227/Mods-For-Hesk) +[![License](https://img.shields.io/badge/license-CC--A--SA-blue.svg)](https://github.com/mkoch227/Mods-for-HESK/blob/master/LICENSE) [![Join the chat at https://gitter.im/mkoch227/Mods-for-HESK](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mkoch227/Mods-for-HESK?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -Mods for HESK is a set of modifications for HESK v2.6.1, a free and popular helpdesk solution. +Mods for HESK is a set of modifications for [HESK](http://www.hesk.com) v2.6.2, a free and popular helpdesk solution. ## Features - A new, responsive user interface @@ -50,8 +51,8 @@ Mods for HESK will be maintained under the Semantic Versioning guidelines as muc `..` And constructed with the following guidelines: - - Breaking backward compatibility bumps the major (and resets the minor and patch) - - New additions, including new minor features, without breaking backward compatibility bumps the minor (and resets the patch) + - Updates to ensure compatibility with new minor/major versions of HESK bumps the major + - New additions, including new minor features, without breaking backward compatibility, or updates to patch versions of HESK bumps the minor (and resets the patch) - Bug fixes and misc minor changes bumps the patch For more information on SemVer, please visit http://semver.org. diff --git a/admin/admin_main.php b/admin/admin_main.php index 002a94ff..65c18403 100644 --- a/admin/admin_main.php +++ b/admin/admin_main.php @@ -1,7 +1,7 @@
-
+
- + - + ?> + + - '); } function removeSpinner(version) { @@ -61,11 +62,11 @@ function changeRowTo(prefix, version, clazz) { } function appendToInstallConsole(text) { - var currentText = $('#console-text').text(); - $('#console-text').append(text).append('
'); + $('#consoleBody').append(text); } function installationFinished() { + appendToInstallConsole(''); var output = '
' + '
' + '

' + diff --git a/install/mods-for-hesk/js/uninstall-scripts.js b/install/mods-for-hesk/js/uninstall-scripts.js new file mode 100644 index 00000000..d85b6a33 --- /dev/null +++ b/install/mods-for-hesk/js/uninstall-scripts.js @@ -0,0 +1,104 @@ +function getTasks() { + return ['status-change', 'autorefresh', 'parent-child', 'settings-access', 'activate-user', + 'notify-note-unassigned', 'user-manage-notification-settings', 'settings-table', 'verified-emails-table', + 'pending-verification-emails-table', 'pending-verification-tickets-table', 'miscellaneous']; +} + +function processUninstallation() { + var tasks = getTasks(); + //-- Change status column to default HESK values + tasks.forEach(function(task) { + startUninstallation(task); + executeUninstallation(task); + }); +} +function startUninstallation(task) { + $('#spinner-'+task) + .removeClass('fa-exclamation-triangle') + .addClass('fa-spinner') + .addClass('fa-pulse'); + changeRowTo('row', task, 'info'); + changeTextTo('span', task, 'In Progress'); +} + +function changeTextTo(prefix, task, text) { + $('#'+prefix+'-'+task).text(text); +} + +function changeRowTo(prefix, task, clazz) { + //-- Remove all classes + $('#'+prefix+'-'+task) + .removeClass('info') + .removeClass('warning') + .removeClass('danger') + .removeClass('success'); + + //-- Re-add the requested class + $('#'+prefix+'-'+task).addClass(clazz); +} + +function executeUninstallation(task) { + appendToInstallConsole('
'); + $.ajax({ + type: 'POST', + url: 'ajax/uninstall-database-ajax.php', + data: { task: task }, + success: function(data) { + markUninstallAsSuccess(task); + checkForCompletion(); + }, + error: function(data) { + if (data.status == 400) { + appendToInstallConsole(''); + } else { + appendToInstallConsole(''); + } + markUninstallAsFailure(task); + } + }); +} + +function checkForCompletion() { + // If all rows have a .success row, installation is finished + var numberOfTasks = getTasks().length; + var numberOfCompletions = $('tr.success').length; + if (numberOfTasks == numberOfCompletions) { + uninstallationFinished(); + } +} + +function uninstallationFinished() { + appendToInstallConsole(''); + var output = '
' + + '
' + + '

' + + '

Awesome! The automated portion of uninstalling Mods for HESK has completed. ' + + 'Please follow these instructions ' + + 'on the Mods for HESK website to finish uninstallation.

' + + '
' + + '
'; + $('#uninstall-information').html(output); +} + +function markUninstallAsSuccess(task) { + removeSpinner(task); + $('#spinner-'+task).addClass('fa-check-circle'); + changeTextTo('span', task, 'Completed Successfully'); + changeRowTo('row', task, 'success'); + appendToInstallConsole(''); +} + +function markUninstallAsFailure(task) { + removeSpinner(task); + $('#spinner-'+task).addClass('fa-times-circle'); + changeRowTo('row', task, 'danger'); + changeTextTo('span', task, 'Uninstall failed! Check the console for more information'); +} + +function removeSpinner(task) { + $('#spinner-'+task) + .removeClass('fa-pulse') + .removeClass('fa-spinner'); +} + +jQuery(document).ready(loadJquery); \ No newline at end of file diff --git a/install/mods-for-hesk/js/version-scripts.js b/install/mods-for-hesk/js/version-scripts.js index 6c744f55..f7116047 100644 --- a/install/mods-for-hesk/js/version-scripts.js +++ b/install/mods-for-hesk/js/version-scripts.js @@ -1,52 +1,65 @@ function processUpdates(startingVersion) { if (startingVersion < 1) { startVersionUpgrade('p140'); - executeUpdate(1, 'p140'); + executeUpdate(1, 'p140', 'Pre 1.4.0'); } else if (startingVersion < 140) { startVersionUpgrade('140'); - executeUpdate(140, '140'); + executeUpdate(140, '140', '1.4.0'); } else if (startingVersion < 141) { startVersionUpgrade('141'); - executeUpdate(141, '141'); + executeUpdate(141, '141', '1.4.1'); } else if (startingVersion < 150) { startVersionUpgrade('150'); - executeUpdate(150, '150'); + executeUpdate(150, '150', '1.5.0'); } else if (startingVersion < 160) { startVersionUpgrade('160'); - executeUpdate(160, '160'); + executeUpdate(160, '160', '1.6.0'); } else if (startingVersion < 161) { startVersionUpgrade('161'); - executeUpdate(161, '161'); + executeUpdate(161, '161', '1.6.1'); } else if (startingVersion < 170) { startVersionUpgrade('170'); - executeUpdate(170, '170'); + executeUpdate(170, '170', '1.7.0'); } else if (startingVersion < 200) { startVersionUpgrade('200'); - executeUpdate(200, '200'); + executeUpdate(200, '200', '2.0.0'); } else if (startingVersion < 201) { startVersionUpgrade('201'); - executeUpdate(201, '201'); + executeUpdate(201, '201', '2.0.1'); + } else if (startingVersion < 210) { + startVersionUpgrade('210'); + executeUpdate(210, '210', '2.1.0'); + } else if (startingVersion < 211) { + startVersionUpgrade('211'); + executeUpdate(211, '211', '2.1.1'); + } else if (startingVersion < 220) { + startVersionUpgrade('220'); + executeUpdate(220, '220', '2.2.0'); + } else if (startingVersion < 221) { + startVersionUpgrade('221'); + executeUpdate(221, '221', '2.2.1'); } else { installationFinished(); } } -function executeUpdate(version, cssclass) { +function executeUpdate(version, cssclass, formattedVersion) { + appendToInstallConsole(''); $.ajax({ type: 'POST', - url: 'ajax/database-ajax.php', + url: 'ajax/install-database-ajax.php', data: { version: version }, success: function(data) { - - markUpdateAsSuccess(cssclass); + markUpdateAsSuccess(cssclass, formattedVersion); if (version == 200) { migrateIpEmailBans('banmigrate', cssclass); + } else { + processUpdates(version); } - processUpdates(version); }, error: function(data) { - appendToInstallConsole('ERROR: ' + data.responseText); + appendToInstallConsole(''); markUpdateAsFailure(cssclass); } }); @@ -54,6 +67,7 @@ function executeUpdate(version, cssclass) { function migrateIpEmailBans(version, cssclass) { startVersionUpgrade(version); + appendToInstallConsole(''); $.ajax({ type: 'POST', url: 'ajax/task-ajax.php', @@ -62,6 +76,7 @@ function migrateIpEmailBans(version, cssclass) { var parsedData = $.parseJSON(data); console.info(parsedData); if (parsedData.status == 'ATTENTION') { + appendToInstallConsole(''); markUpdateAsAttention(version); prepareAttentionPanel(getContentForMigratePrompt(parsedData.users)); } else { @@ -69,7 +84,7 @@ function migrateIpEmailBans(version, cssclass) { } }, error: function(data) { - appendToInstallConsole('ERROR: ' + data.responseText); + appendToInstallConsole(''); markUpdateAsFailure(cssclass); } }); @@ -98,7 +113,7 @@ function runMigration() { function migrateComplete() { $('#attention-row').hide(); - markUpdateAsSuccess('banmigrate'); + markUpdateAsSuccess('banmigrate', 'IP and Email address bans'); processUpdates(200); } diff --git a/install/mods-for-hesk/modsForHesk.php b/install/mods-for-hesk/modsForHesk.php index e72aab0a..db69139d 100644 --- a/install/mods-for-hesk/modsForHesk.php +++ b/install/mods-for-hesk/modsForHesk.php @@ -8,7 +8,7 @@ hesk_dbConnect(); ?> - Mods For HESK 2.0.1 Install / Upgrade + Mods For HESK <?php echo MODS_FOR_HESK_NEW_VERSION; ?> Install / Upgrade @@ -22,10 +22,10 @@ hesk_dbConnect(); -
Mods for HESK 2.0.1 Install / Upgrade
+
Mods for HESK Install / Upgrade
+
+
+ + v2.2.0 +
+
+ + v2.1.1 +
+
+ + v2.1.0 +
+
+ + v2.0.1 +
+
+
- +
+
+
+
+ No previous installation + +

@@ -219,6 +272,23 @@ hesk_dbConnect();
+ + disableAllDisablable(\''.$disableAllExcept.'\')'; diff --git a/install/mods-for-hesk/modsForHeskSql.php b/install/mods-for-hesk/sql/installSql.php similarity index 76% rename from install/mods-for-hesk/modsForHeskSql.php rename to install/mods-for-hesk/sql/installSql.php index 1b40c493..f0ca04b9 100644 --- a/install/mods-for-hesk/modsForHeskSql.php +++ b/install/mods-for-hesk/sql/installSql.php @@ -216,7 +216,7 @@ function execute170FileUpdate() { $file = file_get_contents(HESK_PATH . 'modsForHesk_settings.inc.php'); //-- Only add the additional settings if they aren't already there. - if (strpos($file, 'custom_field_setting') !== true) + if (strpos($file, 'custom_field_setting') === false) { $file .= ' @@ -255,7 +255,7 @@ function execute200FileUpdate() { $file = file_get_contents(HESK_PATH . 'modsForHesk_settings.inc.php'); //-- Only add the additional settings if they aren't already there. - if (strpos($file, 'html_emails') !== true) + if (strpos($file, 'html_emails') === false) { $file .= ' @@ -321,11 +321,119 @@ function migrateBans($creator) { } // END Version 2.0.0 -// BEGIN Version 2.0.1 +// Version 2.0.1 function execute201Scripts() { global $hesk_settings; hesk_dbConnect(); executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '2.0.1' WHERE `Key` = 'modsForHeskVersion'"); } -// END Version 2.0.1 \ No newline at end of file + +// BEGIN Version 2.1.0 +function execute210Scripts() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '2.1.0' WHERE `Key` = 'modsForHeskVersion'"); + + // Some old tables may not have been dropped during the 2.0.0 upgrade. Check and drop if necessary + executeQuery("DROP TABLE IF EXISTS `".hesk_dbEscape($hesk_settings['db_pfix'])."denied_ips`"); + executeQuery("DROP TABLE IF EXISTS `".hesk_dbEscape($hesk_settings['db_pfix'])."denied_emails`"); +} + +function execute210FileUpdate() { + //-- Add the boostrap theme property to modsForHesk_settings.inc.php + $file = file_get_contents(HESK_PATH . 'modsForHesk_settings.inc.php'); + + //-- Only add the additional settings if they aren't already there. + if (strpos($file, 'use_bootstrap_theme') === false) + { + $file .= ' + + //-- Set this to 1 to enable bootstrap-theme.css + $modsForHesk_settings[\'use_bootstrap_theme\'] = 1;'; + } + + return file_put_contents(HESK_PATH.'modsForHesk_settings.inc.php', $file); +} +// END Version 2.1.0 + +// BEGIN Version 2.1.1 +function execute211Scripts() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER IGNORE TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets` CHANGE `dt` `dt` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00'"); + 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`)"); + executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '2.1.1' WHERE `Key` = 'modsForHeskVersion'"); +} + +function execute211FileUpdate() { + //-- Add the new kb article visibility property to modsForHesk_settings.inc.php + $file = file_get_contents(HESK_PATH . 'modsForHesk_settings.inc.php'); + + //-- Only add the additional settings if they aren't already there. + if (strpos($file, 'new_kb_article_visibility') === false) + { + $file .= ' + + //-- Default value for new Knowledgebase article: 0 = Published, 1 = Private, 2 = Draft +$modsForHesk_settings[\'new_kb_article_visibility\'] = 0;'; + } + + return file_put_contents(HESK_PATH.'modsForHesk_settings.inc.php', $file); +} +// END Version 2.1.1 + +// BEGIN Version 2.2.0 +function execute220Scripts() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` ADD COLUMN `IsAutocloseOption` INT NOT NULL DEFAULT 0"); + + // There will only ever be one row + executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` SET `IsAutocloseOption` = 1 WHERE `IsStaffClosedOption` = 1"); + + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` ADD COLUMN `Closable` VARCHAR(10) NOT NULL"); + executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` SET `Closable` = 'yes'"); + executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '2.2.0' WHERE `Key` = 'modsForHeskVersion'"); +} + +function execute220FileUpdate() { + //-- Add the new attachment property to modsForHesk_settings.inc.php + $file = file_get_contents(HESK_PATH . 'modsForHesk_settings.inc.php'); + + //-- Only add the additional settings if they aren't already there. + if (strpos($file, '$modsForHesk_settings[\'attachments\']') === false) + { + $file .= ' + + //-- Setting for adding attachments to email messages. Either 0 for default-HESK behavior, or 1 to send as attachments +$modsForHesk_settings[\'attachments\'] = 0;'; + } + + return file_put_contents(HESK_PATH.'modsForHesk_settings.inc.php', $file); +} +// END Version 2.2.0 + +// BEGIN Version 2.2.1 +function execute221Scripts() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings` SET `Value` = '2.2.1' WHERE `Key` = 'modsForHeskVersion'"); +} +// END Version 2.2.1 \ No newline at end of file diff --git a/install/mods-for-hesk/sql/uninstallSql.php b/install/mods-for-hesk/sql/uninstallSql.php new file mode 100644 index 00000000..d8f2b7b4 --- /dev/null +++ b/install/mods-for-hesk/sql/uninstallSql.php @@ -0,0 +1,139 @@ +fetch_assoc()) + { + + executeQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` SET `status_int` = '".intval($currentResult['status'])."' WHERE `id` = ".$currentResult['id']); + } + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` DROP COLUMN `status`"); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` CHANGE COLUMN `status_int` `status` ENUM('0','1','2','3','4','5') NOT NULL"); + executeQuery("DROP TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses`"); +} + +function removeAutorefresh() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` DROP COLUMN `autorefresh`"); +} + +function removeParentColumn() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` DROP COLUMN `parent`"); +} + +function removeHelpDeskSettingsPermission() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` DROP COLUMN `can_manage_settings`"); +} + +function removeActiveColumn() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` DROP COLUMN `active`"); +} + +function removeNotifyNoteUnassigned() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` DROP COLUMN `notify_note_unassigned`"); +} + +function removeUserManageOwnNotificationSettingsColumn() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("ALTER TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."users` DROP COLUMN `can_change_notification_settings`"); +} + +function removeSettingsTable() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("DROP TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."settings`"); +} + +function removeVerifiedEmailsTable() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("DROP TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."verified_emails`"); +} + +function removePendingVerificationEmailsTable() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("DROP TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."pending_verification_emails`"); +} + +function removeTicketsPendingVerificationTable() { + global $hesk_settings; + + hesk_dbConnect(); + executeQuery("DROP TABLE `".hesk_dbEscape($hesk_settings['db_pfix'])."stage_tickets`"); +} + +function executeMiscellaneousSql() { + global $hesk_settings; + + hesk_dbConnect(); + // These queries are ran in case someone used an unfortunate installation they may have not properly cleaned up tables + executeQuery('DROP TABLE IF EXISTS `'.hesk_dbEscape($hesk_settings['db_pfix']).'denied_ips`'); + executeQuery('DROP TABLE IF EXISTS `'.hesk_dbEscape($hesk_settings['db_pfix']).'denied_emails`'); +} \ No newline at end of file diff --git a/install/mods-for-hesk/uninstallModsForHesk.php b/install/mods-for-hesk/uninstallModsForHesk.php new file mode 100644 index 00000000..34dc18d7 --- /dev/null +++ b/install/mods-for-hesk/uninstallModsForHesk.php @@ -0,0 +1,87 @@ +'; + echo ''; + echo ''; + echo ''; +} +?> + + + Uninstalling Mods for HESK + + + + + + + + + + + + + +
Uninstalling Mods for HESK
+
+ +
+
+
+
Uninstallation Progress
+
+
- : +
+ : - ' . $hesklang['hud'] . ' '; + $cellClass = 'class="success"'; + } elseif ($latest != -1) + { + $cellClass = 'class="warning"'; } - elseif ($latest != -1) + } + ?> + > + + ' . $hesklang['hud'] . ' '; + } + elseif ($latest != -1) { - echo ' ' . $hesklang['beta'] . ' '; ?> ' . $hesklang['beta'] . ' '; ?> ' . $hesklang['hnw'] . ' '; ?> ' . $hesklang['hnw'] . ' '; ?> - - - -
: + + style="padding-left: 10px; padding-bottom: 5px"> + ' . $hesklang['mfh_up_to_date'] . ''; + } else + { + ?> - + - +
@@ -487,31 +534,31 @@ if ( defined('HESK_DEMO') )
- +
- +
- +
- +
- +
@@ -546,31 +593,31 @@ if ( defined('HESK_DEMO') )
- +
- +
- +
- +
- +
@@ -635,49 +682,49 @@ if ( defined('HESK_DEMO') )
- +
- +
- +
- +
- +
- +
- +
- +
@@ -926,11 +973,11 @@ if ( defined('HESK_DEMO') )  
-
+
 
-
+
 
@@ -980,13 +1027,13 @@ if ( defined('HESK_DEMO') )
- +
- +
@@ -1052,7 +1099,7 @@ if ( defined('HESK_DEMO') )
- /> + />
@@ -1068,7 +1115,7 @@ if ( defined('HESK_DEMO') ) ?>
- /> + />
/> + />
@@ -1193,31 +1240,31 @@ if ( defined('HESK_DEMO') )
- +
- +
- +
- +
- +

@@ -1225,7 +1272,7 @@ if ( defined('HESK_DEMO') )
- +

@@ -1234,7 +1281,7 @@ if ( defined('HESK_DEMO') )
- +

@@ -1242,7 +1289,7 @@ if ( defined('HESK_DEMO') )
- +

@@ -1251,7 +1298,7 @@ if ( defined('HESK_DEMO') )
- +

@@ -1372,13 +1419,13 @@ if ( defined('HESK_DEMO') )
- +
- +
@@ -1386,19 +1433,19 @@ if ( defined('HESK_DEMO') )
- /> + />
- /> + />
- /> + />
@@ -1428,13 +1475,13 @@ if ( defined('HESK_DEMO') )
- autocomplete="off" /> + autocomplete="off" />
- autocomplete="off" /> + autocomplete="off" />
@@ -1553,19 +1600,19 @@ if ( defined('HESK_DEMO') )
- /> + />
- /> + />
- /> + />
@@ -1595,13 +1642,13 @@ if ( defined('HESK_DEMO') )
- autocomplete="off" /> + autocomplete="off" />
- autocomplete="off" /> + autocomplete="off" />
@@ -1677,13 +1724,13 @@ if ( defined('HESK_DEMO') )
- +
- +

@@ -1723,7 +1770,7 @@ if ( defined('HESK_DEMO') )
- +
@@ -1926,7 +1973,7 @@ if ( defined('HESK_DEMO') )
- +
@@ -2047,6 +2094,43 @@ if ( defined('HESK_DEMO') ) +
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
@@ -2065,6 +2149,46 @@ if ( defined('HESK_DEMO') ) +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
@@ -2073,6 +2197,8 @@ if ( defined('HESK_DEMO') ) @@ -2084,6 +2210,7 @@ if ( defined('HESK_DEMO') )
+ @@ -2096,17 +2223,31 @@ if ( defined('HESK_DEMO') ) $checkedEcho = ($row['IsClosed'] == 1) ? 'checked="checked"' : ''; $isDisabled = false; if ($row['IsNewTicketStatus'] || $row['IsClosedByClient'] || $row['IsCustomerReplyStatus'] || - $row['IsStaffClosedOption'] || $row['IsStaffReopenedStatus'] || $row['IsDefaultStaffReplyStatus'] - || $row['LockedTicketStatus']) + $row['IsStaffClosedOption'] || $row['IsStaffReopenedStatus'] || $row['IsDefaultStaffReplyStatus'] || + $row['LockedTicketStatus'] || $row['IsAutocloseOption']) { $isDisabled = true; } + $yesSelected = $customersOnlySelected = $staffOnlySelected = $noSelected = ''; + if ($row['Closable'] == 'yes') { $yesSelected = 'selected'; } + elseif ($row['Closable'] == 'conly') { $customersOnlySelected = 'selected'; } + elseif ($row['Closable'] == 'sonly') { $staffOnlySelected = 'selected'; } + else { $noSelected = 'selected'; } + echo ''; echo ''; //Name - echo ''; // Short Name Language File - echo ''; // Long Name Language File - echo ''; // Text Color + echo ''; // Short Name Language File + echo ''; // Long Name Language File + echo ''; // Text Color + echo ''; echo ''; // Resolved Status? echo ''; echo ''; - echo ''; // Short Name Language File - echo ''; // Long Name Language File - echo ''; // Text Color + echo ''; // Short Name Language File + echo ''; // Long Name Language File + echo ''; // Text Color + echo ''; echo ''; // Resolved Status? echo ''; //Empty placeholder where the delete row is. echo ''; @@ -2140,7 +2289,7 @@ if ( defined('HESK_DEMO') )
fetch_assoc()) { $selectedEcho = ($row['IsClosedByClient'] == 1) ? 'selected="selected"' : ''; @@ -2170,7 +2319,7 @@ if ( defined('HESK_DEMO') )
fetch_assoc()) { $selectedEcho = ($row['IsStaffClosedOption'] == 1) ? 'selected="selected"' : ''; @@ -2200,7 +2349,7 @@ if ( defined('HESK_DEMO') )
fetch_assoc()) { $selectedEcho = ($row['IsDefaultStaffReplyStatus'] == 1) ? 'selected="selected"' : ''; @@ -2240,6 +2389,21 @@ if ( defined('HESK_DEMO') )
+
+ +
+ +
+
@@ -2481,17 +2645,87 @@ function hesk_getLatestVersion() } // END hesk_getLatestVersion() - function hesk_cacheLatestVersion($latest) { - global $hesk_settings; + global $hesk_settings; - @file_put_contents(HESK_PATH . $hesk_settings['attach_dir'] . '/__latest.txt', time() . '|' . $latest); + @file_put_contents(HESK_PATH . $hesk_settings['attach_dir'] . '/__latest.txt', time() . '|' . $latest); - return $latest; + return $latest; } // END hesk_cacheLatestVersion() +function hesk_checkMfhVersion($currentVersion) +{ + if ($latest = hesk_getMfhLatestVersion() ) + { + if ( strlen($latest) > 12 ) + { + return -1; + } + elseif ($latest == $currentVersion) + { + return true; + } + else + { + return $latest; + } + } + else + { + return -1; + } +} + +function hesk_getMfhLatestVersion() +{ + global $hesk_settings; + + // Do we have a cached version file? + if ( file_exists(HESK_PATH . $hesk_settings['attach_dir'] . '/__latest-mfh.txt') ) + { + if ( preg_match('/^(\d+)\|([\d.]+)+$/', @file_get_contents(HESK_PATH . $hesk_settings['attach_dir'] . '/__latest-mfh.txt'), $matches) && (time() - intval($matches[1])) < 3600 ) + { + return $matches[2]; + } + } + + // No cached file or older than 3600 seconds, try to get an update + $hesk_version_url = 'http://mods-for-hesk.mkochcs.com/latestversion.php'; + + // Try using cURL + if ( function_exists('curl_init') ) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $hesk_version_url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 6); + $latest = curl_exec($ch); + curl_close($ch); + return hesk_cacheMfhLatestVersion($latest); + } + + // Try using a simple PHP function instead + if ($latest = file_get_contents($hesk_version_url) ) + { + return hesk_cacheMfhLatestVersion($latest); + } + + // Can't check automatically, will need a manual check + return false; +} + +function hesk_cacheMfhLatestVersion($latest) +{ + global $hesk_settings; + + @file_put_contents(HESK_PATH . $hesk_settings['attach_dir'] . '/__latest-mfh.txt', time() . '|' . $latest); + + return $latest; + +} + function hesk_testLanguage($return_options = 0) { diff --git a/admin/admin_settings_save.php b/admin/admin_settings_save.php index a59bbaea..20e13c16 100644 --- a/admin/admin_settings_save.php +++ b/admin/admin_settings_save.php @@ -1,7 +1,7 @@ fetch_assoc()) } else { //-- Update the information in the database with what is on the page - $query = "UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` SET `ShortNameContentKey` = ?, `TicketViewContentKey` = ?, `TextColor` = ?, `IsClosed` = ? WHERE `ID` = ?"; + $query = "UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` SET `ShortNameContentKey` = ?, `TicketViewContentKey` = ?, `TextColor` = ?, `IsClosed` = ?, `Closable` = ? WHERE `ID` = ?"; $stmt = hesk_dbConnect()->prepare($query); $isStatusClosed = (isset($_POST['s'.$row['ID'].'_isClosed']) ? 1 : 0); - $stmt->bind_param('sssii', $_POST['s'.$row['ID'].'_shortName'], $_POST['s'.$row['ID'].'_longName'], $_POST['s'.$row['ID'].'_textColor'], $isStatusClosed, $row['ID']); + $stmt->bind_param('sssisi', $_POST['s'.$row['ID'].'_shortName'], $_POST['s'.$row['ID'].'_longName'], $_POST['s'.$row['ID'].'_textColor'], $isStatusClosed, $_POST['s'.$row['ID'].'_closable'], $row['ID']); $stmt->execute(); } } @@ -552,11 +552,10 @@ if ($_POST['sN_shortName'] != null && $_POST['sN_longName'] != null && $_POST['s { //-- The next ID is equal to the number of rows, since the IDs are zero-indexed. $nextValue = hesk_dbQuery('SELECT * FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses`')->num_rows; - $insert = "INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` (`ID`, `ShortNameContentKey`, `TicketViewContentKey`, `TextColor`, `IsClosed`) VALUES (?, ?, ?, ?, ?)"; - $stmt = hesk_dbConnect()->prepare($insert); $isClosed = isset($_POST['sN_isClosed']) ? 1 : 0; - $stmt->bind_param('isssi', $nextValue, $_POST['sN_shortName'], $_POST['sN_longName'], $_POST['sN_textColor'], $isClosed); - $stmt->execute(); + $insert = "INSERT INTO `".hesk_dbEscape($hesk_settings['db_pfix'])."statuses` (`ID`, `ShortNameContentKey`, `TicketViewContentKey`, `TextColor`, `IsClosed`, `Closable`) + VALUES (".$nextValue.", '".hesk_dbEscape($_POST['sN_shortName'])."', '".hesk_dbEscape($_POST['sN_longName'])."', '".hesk_dbEscape($_POST['sN_textColor'])."', ".$isClosed.", '".hesk_dbEscape($_POST['sN_closable'])."')"; + hesk_dbQuery($insert); } //-- Update default status for actions @@ -605,6 +604,12 @@ $stmt = hesk_dbConnect()->prepare($updateQuery); $stmt->bind_param('i', $_POST['lockedTicketStatus']); $stmt->execute(); +hesk_dbConnect()->query($defaultQuery . "`IsAutocloseOption` = 0"); +$updateQuery = $defaultQuery . "`IsAutocloseOption` = 1 WHERE `ID` = ?"; +$stmt = hesk_dbConnect()->prepare($updateQuery); +$stmt->bind_param('i', $_POST['autocloseTicketOption']); +$stmt->execute(); + $set['hesk_version'] = $hesk_settings['hesk_version']; // Save the modsForHesk_settings.inc.php file @@ -613,6 +618,9 @@ $set['show-icons'] = empty($_POST['show-icons']) ? 0 : 1; $set['custom-field-setting'] = empty($_POST['custom-field-setting']) ? 0 : 1; $set['customer-email-verification-required'] = empty($_POST['email-verification']) ? 0 : 1; $set['html_emails'] = empty($_POST['html_emails']) ? 0 : 1; +$set['use_bootstrap_theme'] = empty($_POST['use_bootstrap_theme']) ? 0 : 1; +$set['new_kb_article_visibility'] = hesk_checkMinMax( intval( hesk_POST('new_kb_article_visibility') ) , 0, 2, 2); +$set['mfh_attachments'] = empty($_POST['email_attachments']) ? 0 : 1; if ($set['customer-email-verification-required']) { @@ -663,7 +671,16 @@ $modsForHesk_settings[\'html_emails\'] = '.$set['html_emails'].'; //-- Mailgun Settings $modsForHesk_settings[\'use_mailgun\'] = '.$set['use_mailgun'].'; $modsForHesk_settings[\'mailgun_api_key\'] = \''.$set['mailgun_api_key'].'\'; -$modsForHesk_settings[\'mailgun_domain\'] = \''.$set['mailgun_domain'].'\';'; +$modsForHesk_settings[\'mailgun_domain\'] = \''.$set['mailgun_domain'].'\'; + +//-- Set this to 1 to enable bootstrap-theme.css +$modsForHesk_settings[\'use_bootstrap_theme\'] = '.$set['use_bootstrap_theme'].'; + +//-- Default value for new Knowledgebase article: 0 = Published, 1 = Private, 2 = Draft +$modsForHesk_settings[\'new_kb_article_visibility\'] = '.$set['new_kb_article_visibility'].'; + +//-- Setting for adding attachments to email messages. Either 0 for default-HESK behavior, or 1 to send as attachments +$modsForHesk_settings[\'attachments\'] = '.$set['mfh_attachments'].';'; // Write the file if ( ! file_put_contents(HESK_PATH . 'modsForHesk_settings.inc.php', $modsForHesk_file_content) ) diff --git a/admin/admin_submit_ticket.php b/admin/admin_submit_ticket.php index 3d9548e1..2ba24c9b 100644 --- a/admin/admin_submit_ticket.php +++ b/admin/admin_submit_ticket.php @@ -1,7 +1,7 @@ '".hesk_dbEscape($trackingID)."' ORDER BY `lastchange` DESC LIMIT 5"); + while ($recentRow = hesk_dbFetchAssoc($recentTicketsSql)) { + if ($recentTickets === NULL) { + $recentTickets = array(); + } + array_push($recentTickets, $recentRow); + } + + if ($recentTickets !== NULL) { + $recentTicketsWithStatuses = array(); + foreach ($recentTickets as $recentTicket) { + $newRecentTicket = $recentTicket; + $thisTicketStatusRS = hesk_dbQuery("SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `ID` = " . intval($recentTicket['status'])); + $theStatusRow = hesk_dbFetchAssoc($thisTicketStatusRS); + $newRecentTicket['statusText'] = $hesklang[$theStatusRow['ShortNameContentKey']]; + $newRecentTicket['statusColor'] = $theStatusRow['TextColor']; + array_push($recentTicketsWithStatuses, $newRecentTicket); + } + $recentTickets = $recentTicketsWithStatuses; + } +} + /* Print admin navigation */ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); ?> @@ -672,7 +703,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
'.$hesklang['asss'].']' : $hesklang['unas']); + ($can_assign_self ? $hesklang['unas'].' — '.$hesklang['asss'].'' : $hesklang['unas']); ?>
  • @@ -789,6 +820,19 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
  • + +
  • + + +

    + + '.$recentTicket['trackid'].''; ?> +

    + +
  • + @@ -847,18 +891,19 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); } } - $isTicketClosedSql = 'SELECT `IsClosed` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `ID` = '.$ticket['status']; + $isTicketClosedSql = 'SELECT `IsClosed`, `Closable` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `ID` = '.$ticket['status']; $isTicketClosedRow = hesk_dbQuery($isTicketClosedSql)->fetch_assoc(); $isTicketClosed = $isTicketClosedRow['IsClosed']; + $isClosable = $isTicketClosedRow['Closable'] == 'yes' || $isTicketClosedRow['Closable'] == 'sonly'; echo '
    '.$hesklang[$row['ShortNameContentKey']].' + + '; if ($isDisabled) @@ -2123,9 +2264,17 @@ if ( defined('HESK_DEMO') ) //Print out an additional blank space for adding a status echo '
    '.$hesklang['addNew'].' + +
    '; + echo ''; + echo ''; foreach ($att as $myatt) { - $columnNumber++; - if ($columnNumber > 4) - { - echo '
    '; - $columnNumber = 1; - } - list($att_id, $att_name) = explode('#', $myatt); - - echo '
    '; + list($att_id, $att_name) = explode('#', $myatt); $fileparts = pathinfo($att_name); $fontAwesomeIcon = hesk_getFontAwesomeIconForFileExtension($fileparts['extension']); echo ' -
    -
    '; +
    + + + + '; - echo ''; } - echo ''; + echo '
     '.$hesklang['file_name'].''.$hesklang['action'].'
    '; //-- File is an image if ($fontAwesomeIcon == 'fa fa-file-image-o') { //-- Get the actual image location and display a thumbnail. It will be linked to a modal to view a larger size. $path = hesk_getSavedNameUrlForAttachment($att_id); if ($path == '') { - echo ''; + echo ''; } else { - echo ''.$hesklang['image'].''; + echo ' + '.$hesklang['image'].' + '; echo ' @@ -1412,25 +1449,28 @@ function hesk_listAttachments($attachments='', $reply=0, $white=1) //-- Display the FontAwesome icon in the panel's body echo ''; } - echo ' - +

    '.$att_name.'

    +
    '; /* Can edit and delete tickets? */ if ($can_edit && $can_delete) { echo ' '; } - echo ' - -
    -


    '.$att_name.'

    - '; - echo ' - + echo ' + + '; + echo ' +
    '; return true; } // End hesk_listAttachments() @@ -1449,7 +1489,7 @@ function hesk_getSavedNameUrlForAttachment($att_id) function hesk_getFontAwesomeIconForFileExtension($fileExtension) { - $imageExtensions = array('jpg','png','bmp','gif'); + $imageExtensions = array('jpg','jpeg','png','bmp','gif'); //-- Word, Excel, and PPT file extensions: http://en.wikipedia.org/wiki/List_of_Microsoft_Office_filename_extensions $wordFileExtensions = array('doc','docx','dotm','dot','docm','docb'); @@ -1471,6 +1511,7 @@ function hesk_getFontAwesomeIconForFileExtension($fileExtension) $textFileExtensions = array('txt'); $icon = 'fa fa-file-'; + $fileExtension = strtolower($fileExtension); if (in_array($fileExtension, $imageExtensions)) { $icon.='image-o'; } elseif (in_array($fileExtension, $wordFileExtensions)) { @@ -1830,7 +1871,7 @@ function hesk_printReplyForm() {
    - +
    '; break; @@ -396,7 +396,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
    -
    '; @@ -436,7 +436,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
    - +
    '; @@ -449,7 +449,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
    - +
    diff --git a/admin/export.php b/admin/export.php index 9255b402..fbe98b2a 100644 --- a/admin/export.php +++ b/admin/export.php @@ -1,7 +1,7 @@ ' . "\n"; + $tmp .= ' ' . "\n"; } } diff --git a/admin/find_tickets.php b/admin/find_tickets.php index 2e0759b1..81b79834 100644 --- a/admin/find_tickets.php +++ b/admin/find_tickets.php @@ -1,7 +1,7 @@ 0) - { - global $ticket; - // Load required functions? - if ( ! function_exists('hesk_notifyCustomer') ) - { - require(HESK_PATH . 'inc/email_functions.inc.php'); - } - - while ($ticket = hesk_dbFetchAssoc($result)) - { - $ticket['dt'] = hesk_date($ticket['dt'], true); - $ticket['lastchange'] = hesk_date($ticket['lastchange'], true); - $ticket = hesk_ticketToPlain($ticket, 1, 0); - hesk_notifyCustomer('ticket_closed'); + $closedStatusRs = hesk_dbQuery('SELECT `ID`, `Closable` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsDefaultStaffReplyStatus` = 1'); + $closedStatus = hesk_dbFetchAssoc($closedStatusRs); + // Are we allowed to close tickets in this status? + if ($closedStatus['Closable'] == 'yes' || $closedStatus['Closable'] == 'sonly') { + // Notify customer of closed ticket? + if ($hesk_settings['notify_closed']) { + // Get list of tickets + $result = hesk_dbQuery("SELECT * FROM `" . $hesk_settings['db_pfix'] . "tickets` WHERE `status` = " . $closedStatus['ID'] . " AND `lastchange` <= '" . hesk_dbEscape($dt) . "' "); + if (hesk_dbNumRows($result) > 0) { + global $ticket; + + // Load required functions? + if (!function_exists('hesk_notifyCustomer')) { + require(HESK_PATH . 'inc/email_functions.inc.php'); + } + + while ($ticket = hesk_dbFetchAssoc($result)) { + $ticket['dt'] = hesk_date($ticket['dt'], true); + $ticket['lastchange'] = hesk_date($ticket['lastchange'], true); + $ticket = hesk_ticketToPlain($ticket, 1, 0); + hesk_notifyCustomer('ticket_closed'); + } } } - } - // Update ticket statuses and history in database - hesk_dbQuery("UPDATE `".$hesk_settings['db_pfix']."tickets` SET `status`='3', `closedat`=NOW(), `closedby`='-1', `history`=CONCAT(`history`,'".hesk_dbEscape($revision)."') WHERE `status` = '2' AND `lastchange` <= '".hesk_dbEscape($dt)."' "); + // Update ticket statuses and history in database if we're allowed to do so + $defaultCloseRs = hesk_dbQuery('SELECT `ID` FROM `'.hesk_dbEscape($hesk_settings['db_pfix']).'statuses` WHERE `IsAutocloseOption` = 1'); + $defaultCloseStatus = hesk_dbFetchAssoc($defaultCloseRs); + hesk_dbQuery("UPDATE `" . $hesk_settings['db_pfix'] . "tickets` SET `status`=".intval($defaultCloseStatus['ID']).", `closedat`=NOW(), `closedby`='-1', `history`=CONCAT(`history`,'" . hesk_dbEscape($revision) . "') WHERE `status` = '".$closedStatus['ID']."' AND `lastchange` <= '" . hesk_dbEscape($dt) . "' "); + } } /* Redirect to the destination page */ @@ -326,171 +328,185 @@ function print_login() hesk_handle_messages(); ?>
    - + +'; + $markup .= ''; + $markup .= ''; + return $markup; + } else { + $markup = ''; + $markup .= ''; + $markup .= ''; + return $markup; + } +} + +function save() { + global $hesklang; + + $filePath = HESK_PATH . 'language/'.$_POST['language'].'/emails/'.$_POST['template']; + if ($_POST['html'] == '1') { + $filePath = HESK_PATH . 'language/'.$_POST['language'].'/emails/html/'.$_POST['template']; + } + + $success = file_put_contents($filePath, $_POST['text']); + if ($success === false) { + hesk_process_messages($hesklang[''], 'manage_email_templates.php'); + } else { + $message = sprintf($hesklang['email_template_saved'], $_POST['template']); + hesk_process_messages($message,'manage_email_templates.php','SUCCESS'); + } +} + +function getSpecialTagMap() { + global $hesk_settings, $modsForHesk_settings, $hesklang; + + $map = array(); + $map['%%NAME%%'] = $hesklang['customer_name']; + $map['%%EMAIL%%'] = $hesklang['customer_email']; + $map['%%SUBJECT%%'] = $hesklang['ticket_subject']; + $map['%%MESSAGE%%'] = $hesklang['ticket_message']; + $map['%%CREATED%%'] = $hesklang['ticket_created']; + $map['%%UPDATED%%'] = $hesklang['ticket_updated']; + $map['%%TRACK_ID%%'] = $hesklang['ticket_trackID']; + $map['%%TRACK_URL%%'] = $hesklang['ticket_url']; + $map['%%SITE_TITLE%%'] = $hesklang['wbst_title']; + $map['%%SITE_URL%%'] = $hesklang['wbst_url']; + $map['%%CATEGORY%%'] = $hesklang['ticket_category']; + $map['%%OWNER%%'] = $hesklang['ticket_owner']; + $map['%%PRIORITY%%'] = $hesklang['ticket_priority']; + $map['%%STATUS%%'] = $hesklang['ticket_status']; + + $i = 1; + foreach ($hesk_settings['custom_fields'] as $key => $value) { + if ($value['use']) { + $uppercaseKey = strtoupper($key); + $map['%%'.$uppercaseKey.'%%'] = sprintf($hesklang['custom_field_x'], $i++); + } + } + + return $map; +} \ No newline at end of file diff --git a/admin/manage_knowledgebase.php b/admin/manage_knowledgebase.php index 69029a3a..e94fd461 100644 --- a/admin/manage_knowledgebase.php +++ b/admin/manage_knowledgebase.php @@ -1,7 +1,7 @@
    +
    - +
    - +
    - +
    @@ -398,7 +407,7 @@ if (!isset($_SESSION['hide']['new_article']))
    - /> + />

    @@ -1399,9 +1408,9 @@ function edit_article()
    - +
    - +
    @@ -1409,7 +1418,7 @@ function edit_article()


    - +
    diff --git a/admin/manage_ticket_templates.php b/admin/manage_ticket_templates.php index cf439916..c6a5a161 100644 --- a/admin/manage_ticket_templates.php +++ b/admin/manage_ticket_templates.php @@ -1,7 +1,7 @@
    - >
    @@ -232,7 +232,7 @@ $num = hesk_dbNumRows($result);
    -
    +
    '; break; @@ -462,7 +462,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
    - '.$hesklang['date_format'].'
    @@ -489,7 +489,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); echo '
    -
    +
    '; break; @@ -509,7 +509,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); echo '
    -
    +
    '; } } @@ -642,13 +642,13 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); ';} else {echo '
    ';} ?>
    - +
    ';} else {echo '
    ';} ?>
    - +
    @@ -804,7 +804,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); echo '
    -
    +
    '; break; @@ -824,7 +824,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
    - '.$hesklang['date_format'].'
    @@ -886,7 +886,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); echo '
    -
    +
    '; break; @@ -906,7 +906,7 @@ require_once(HESK_PATH . 'inc/show_admin_nav.inc.php'); echo '
    -
    +
    '; } } diff --git a/admin/options.php b/admin/options.php index f97ac4a2..97432a99 100644 --- a/admin/options.php +++ b/admin/options.php @@ -1,7 +1,7 @@ ">
    - +
    + + '.$hesklang['email_templates'].' + + '; + } + ?>
    +
    +
    + -
    +
    +
    +

    - +
    - +
    /> diff --git a/install/index.php b/install/index.php index 3873d1a3..31b45f06 100644 --- a/install/index.php +++ b/install/index.php @@ -1,64 +1,10 @@ - -
    - HESK Logo -

    -

    Thank you for downloading HESK. Please choose an option below.

    -
    -
    - Setup -


    Install a new copy of HESK on your server

    -

    - Upgrade -


    Upgrade existing HESK installation to version

    -

    - Install / Upgrade Mods for HESK -


    Install or upgrade existing Mods for HESK installation to version

    -
    - - + + + Install | Redirecting... + + + + + diff --git a/install/install.php b/install/install.php index fb2b5d38..18ed1ef5 100644 --- a/install/install.php +++ b/install/install.php @@ -1,7 +1,7 @@ + + + + + + + + + \ No newline at end of file diff --git a/install/mods-for-hesk/installModsForHesk.php b/install/mods-for-hesk/installModsForHesk.php index da3aaf54..5b7480b3 100644 --- a/install/mods-for-hesk/installModsForHesk.php +++ b/install/mods-for-hesk/installModsForHesk.php @@ -37,6 +37,18 @@ function echoInitialVersionRows($version) { if ($version < 201) { printRow('v2.0.1'); } + if ($version < 210) { + printRow('v2.1.0'); + } + if ($version < 211) { + printRow('v2.1.1'); + } + if ($version < 220) { + printRow('v2.2.0'); + } + if ($version < 221) { + printRow('v2.2.1'); + } } function printRow($version) { @@ -119,8 +131,16 @@ function printRow($version) {
    Console
    -
    -

    +
    + + + + + + + + +
    SeverityMessage
    diff --git a/install/mods-for-hesk/js/ui-scripts.js b/install/mods-for-hesk/js/ui-scripts.js index 158cd758..1e32489f 100644 --- a/install/mods-for-hesk/js/ui-scripts.js +++ b/install/mods-for-hesk/js/ui-scripts.js @@ -17,11 +17,12 @@ function startVersionUpgrade(version) { changeTextTo('span', version, 'In Progress'); } -function markUpdateAsSuccess(version) { +function markUpdateAsSuccess(version, formattedVersion) { removeSpinner(version); $('#spinner-'+version).addClass('fa-check-circle'); changeTextTo('span', version, 'Completed Successfully'); changeRowTo('row', version, 'success'); + appendToInstallConsole('
    SUCCESSUpdates for ' + formattedVersion + ' complete
    SUCCESSInstallation complete
    INFOStarting task code: ' + task + '
    ERRORThe task '+ task +' was not recognized. Check the value submitted and try again.
    ERROR'+ data.responseText + '
    SUCCESSUninstallation complete
    SUCCESSUninstall for task code: ' + task + ' complete
    INFOStarting updates for ' + formattedVersion + '
    ERROR'+ data.responseText + '
    INFOChecking for IP / Email address bans to migrate
    WARNINGYour response is needed. Please check above.
    ERROR' + data.responseText + '
    '.$text.' Waiting...
    + + + +
    +
    +
    +
    + +
    +
    +
    +
    Console
    +
    + + + + + + + + +
    SeverityMessage
    +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/knowledgebase.php b/knowledgebase.php index 3777f33d..309ceae7 100644 --- a/knowledgebase.php +++ b/knowledgebase.php @@ -1,7 +1,7 @@ '; require_once(HESK_PATH . 'inc/footer.inc.php'); exit(); @@ -276,8 +276,15 @@ function hesk_show_kb_article($artid) { hesk_dbQuery("UPDATE `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` SET `views`=`views`+1 WHERE `id`={$artid} LIMIT 1"); } + if (!isset($_GET['suggest'])) { + $historyNumber = isset($_GET['rated']) ? '-2' : '-1'; + $goBackText = ' + '; + } else { + $goBackText = ''; + } - echo '

    '.$article['subject'].'

    + echo '

    '.$goBackText.' '.$article['subject'].'

    '.$hesklang['as'].'

    ' @@ -409,22 +416,7 @@ function hesk_show_kb_article($artid)
    - - - -

    - -

     

    - '.$hesklang['kb_cat'].': '.$thiscat['name'].' -

    Go back

    + echo '

     '.$hesklang['kb_cat'].': '.$thiscat['name'].'

    '; @@ -468,153 +459,137 @@ function hesk_show_kb_category($catid, $is_search = 0) { { ?> -

    -
    - - +
    +
    +

    +
    +
    - '; - } + if ($i == 1) + { + echo ''; + } - echo ' - '; + $i = 0; + } + $i++; + } + /* Finish the table if needed */ + if ($i != 1) + { + for ($j=1;$j<=$per_col;$j++) + { + echo ''; + if ($i == $per_col) + { + echo ''; + break; + } + $i++; + } + } - - - -
    - - - '; + echo ' + '; - if ($i == $per_col) - { - echo ''; - $i = 0; - } - $i++; - } - /* Finish the table if needed */ - if ($i != 1) - { - for ($j=1;$j<=$per_col;$j++) - { - echo ''; - if ($i == $per_col) - { - echo ''; - break; - } - $i++; - } - } - - ?> -
     '.$cat['name'].'
    + + + '; - /* Print most popular/sticky articles */ - if ($hesk_settings['kb_numshow'] && $cat['articles']) - { - $res = hesk_dbQuery("SELECT `id`,`subject` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` WHERE `catid`='{$cat['id']}' AND `type`='0' ORDER BY `sticky` DESC, `views` DESC, `art_order` ASC LIMIT " . (intval($hesk_settings['kb_numshow']) + 1) ); - $num = 1; - while ($art = hesk_dbFetchAssoc($res)) - { - echo ' + /* Print most popular/sticky articles */ + if ($hesk_settings['kb_numshow'] && $cat['articles']) + { + $res = hesk_dbQuery("SELECT `id`,`subject` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."kb_articles` WHERE `catid`='{$cat['id']}' AND `type`='0' ORDER BY `sticky` DESC, `views` DESC, `art_order` ASC LIMIT " . (intval($hesk_settings['kb_numshow']) + 1) ); + $num = 1; + while ($art = hesk_dbFetchAssoc($res)) + { + echo ' '; - if ($num == $hesk_settings['kb_numshow']) - { - break; - } - else - { - $num++; - } - } - if (hesk_dbNumRows($res) > $hesk_settings['kb_numshow']) - { - echo ''; - } - } - - echo ' + if ($num == $hesk_settings['kb_numshow']) + { + break; + } + else + { + $num++; + } + } + if (hesk_dbNumRows($res) > $hesk_settings['kb_numshow']) + { + echo ''; + } + } + + echo '
     '.$cat['name'].'
           '.$art['subject'].'
    » '.$hesklang['m'].'
    » '.$hesklang['m'].'
     
    + if ($i == $per_col) + { + echo '
     
     
    + ?> + + 0 ?> -

    -
    - - - - - '; + } + else + { + $rat = ''; + } - - -
    - - '.$hesklang['noac'].'

    '; - } - else - { - echo '
    '; - while ($article = hesk_dbFetchAssoc($res)) - { - $txt = hesk_kbArticleContentPreview($article['content']); - - if ($hesk_settings['kb_rating']) - { - $alt = $article['rating'] ? sprintf($hesklang['kb_rated'], sprintf("%01.1f", $article['rating'])) : $hesklang['kb_not_rated']; - $rat = ''; - } - else - { - $rat = ''; - } +
    +
    +

    +
    +
    '.$alt.'
    + + '; + } + else + { + while ($article = hesk_dbFetchAssoc($res)) + { + $txt = hesk_kbArticleContentPreview($article['content']); - echo ' - - - '; - } - echo '
    '.$hesklang['noac'].'
    - - - - - '.$rat.' - -
    '.$article['subject'].'
    - - - - - -
    '.$txt.'
    -
    '; - } - ?> + if ($hesk_settings['kb_rating']) + { + $alt = $article['rating'] ? sprintf($hesklang['kb_rated'], sprintf("%01.1f", $article['rating'])) : $hesklang['kb_not_rated']; + $rat = '
    '.$alt.'
    + echo ' + + + + '.$article['subject'].' +
    + '.$txt.' + + '.$rat.' + '; + } + } + ?> + + + diff --git a/language/en/emails/html/category_moved.txt b/language/en/emails/html/category_moved.txt index a2d87b36..8f254ac9 100644 --- a/language/en/emails/html/category_moved.txt +++ b/language/en/emails/html/category_moved.txt @@ -1,10 +1,7 @@

    Hello,

    A new support ticket has been moved to your category. Ticket details:

    -

    Ticket subject: %%SUBJECT%%
    -Tracking ID: %%TRACK_ID%%

    -

    You can manage this ticket here: -%%TRACK_URL%%

    -
    +

    Ticket subject: %%SUBJECT%%
    Tracking ID: %%TRACK_ID%%

    +

    You can manage this ticket here: %%TRACK_URL%%

    +

     

    Regards,

    -%%SITE_TITLE%%
    -%%SITE_URL%% \ No newline at end of file +

    %%SITE_TITLE%%
    %%SITE_URL%%

    \ No newline at end of file diff --git a/language/en/text.php b/language/en/text.php index 22a5abc2..cfa575ca 100644 --- a/language/en/text.php +++ b/language/en/text.php @@ -2,7 +2,7 @@ /* * Language file for Help Desk Software HESK (www.hesk.com) * Language: ENGLISH -* Version: 2.6.0 +* Version: 2.6.1 * Author: Klemen Stirn (http://www.hesk.com) * * !!! This file must be saved in UTF-8 encoding without byte order mark (BOM) !!! @@ -21,8 +21,72 @@ $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 2.2.1 +$hesklang['popart_no_colon']='Top Knowledgebase Articles'; // same as $hesklang['popart'] but without a colon (:) +$hesklang['latart_no_colon']='Latest Knowledgebase Articles'; // same as $hesklang['latart'] but without a colon (:) +$hesklang['ac_no_colon']='Articles in this Category'; // same as $hesklang['ac'] but without a colon (:) + +// ADDED OR MODIFIED IN Mods for HESK 2.2.0 +$hesklang['email_templates'] = 'Email templates'; +$hesklang['email_templates_intro'] = 'You can edit your plaintext and HTML email templates here.'; +$hesklang['edit_plain_text_template'] = 'Edit plain text template'; +$hesklang['edit_html_template'] = 'Edit HTML template'; +$hesklang['editing_plain_text_template'] = 'Editing plain text template %s'; // %s: The name of the template file, then language name +$hesklang['editing_html_template'] = 'Editing HTML template %s'; // %s: The name of the template file, then language name +$hesklang['show_special_tags'] = 'Show Special Tags'; +$hesklang['hide_special_tags'] = 'Hide Special Tags'; +$hesklang['special_tag'] = 'Special Tag'; +$hesklang['description'] = 'Description'; +$hesklang['customer_name'] = 'Customer name'; +$hesklang['customer_email'] = 'Customer email'; +$hesklang['ticket_subject'] = 'Ticket subject'; +$hesklang['ticket_message'] = 'Ticket/Reply message'; +$hesklang['ticket_created'] = 'Date and time of ticket submission'; +$hesklang['ticket_updated'] = 'Date and time of ticket last update'; +$hesklang['ticket_url'] = 'Ticket URL address'; +$hesklang['ticket_category'] = 'Ticket category'; +$hesklang['ticket_owner'] = 'Staff member assigned to the ticket'; +$hesklang['ticket_priority'] = 'Ticket priority'; +$hesklang['custom_field_x'] = 'Custom field %s'; // %s: Custom field #1-20 +$hesklang['email_template_saved'] = 'The email template %s has been saved.'; // %s: Template file name +$hesklang['error_saving_template'] = 'An error occurred when trying to save the email template!'; +$hesklang['can_man_email_tpl'] = 'Edit email templates'; +$hesklang['email_template_directory_not_writable'] = 'The email template %s is not writable by HESK. Please CHMOD it to 0666.'; // %s: template file name +$hesklang['closable_question'] = 'Closable?'; +$hesklang['closable_description'] = 'This setting is ignored if the "Closed?" checkbox is checked for this status. +

    Determines if the customer staff is able to close a ticket in this status. +

    Yes: Both customers and staff can close a ticket in this status. +
    Customers only: Customers can close a ticket in this status, but staff cannot. +
    Staff only: Staff can close a ticket in this status, but customers cannot. +
    No: No one is allowed to close a ticket in this status.'; // " = " +$hesklang['customers_only'] = 'Customers only'; +$hesklang['staff_only'] = 'Staff only'; +$hesklang['yes_title_case'] = 'Yes'; +$hesklang['no_title_case'] = 'No'; +$hesklang['autoclose_ticket_status'] = 'When a ticket is closed automatically, change the status to'; +$hesklang['recent_tickets'] = 'Recent tickets'; +$hesklang['current_status_colon'] = 'Current status: %s'; // %s: status name (i.e. "Resolved", "New", etc.) +$hesklang['email_attachments'] = 'Email attachments'; +$hesklang['email_attachments_help'] = 'Show attachments as links: Links to attachments will be appended at the end of the email. +

    Attach directly to email: Attachments will be embedded directly into emails.'; +$hesklang['show_attachments_as_links'] = 'Show attachments as links'; +$hesklang['attach_directly_to_email'] = 'Attach directly to email'; + +// ADDED OR MODIFIED IN Mods for HESK 2.1.1 +$hesklang['new_article_default_type'] = 'Default Type for New Articles'; +$hesklang['new_article_default_type_help'] = 'Choose the default type for new knowledgebase articles.'; +$hesklang['kb_draft3'] = 'The article is saved but not yet published. It can only be read by staff who has permission to + manage knowledgebase articles.'; // This is exactly the same as kb_draft2 with all HTML removed +$hesklang['file_name'] = 'File Name'; +$hesklang['action'] = 'Action'; +$hesklang['click_to_preview'] = 'Click to preview'; +$hesklang['attachment_removed'] = 'This attachment has been removed and cannot be viewed / downloaded'; + // ADDED OR MODIFIED IN Mods for HESK 2.1.0 $hesklang['e_mfh_settings'] = 'You will not be able to save your settings unless this file is writable by the script (CHMOD to 666)!'; +$hesklang['mfh_up_to_date'] = 'Mods for HESK is up to date'; +$hesklang['use_bootstrap_theme'] = 'Use Boostrap Theme CSS'; +$hesklang['use_bootstrap_theme_help'] = 'Enable this to use the bootstrap-theme.css file. Use this for a more 3D look and feel, or disable it for a flatter look.'; // ADDED OR MODIFIED IN Mods For HESK 2.0.0 $hesklang['saved_ticket_tpl'] = 'Saved Templates'; diff --git a/modsForHesk_settings.inc.php b/modsForHesk_settings.inc.php index 850674d5..1ff48431 100644 --- a/modsForHesk_settings.inc.php +++ b/modsForHesk_settings.inc.php @@ -31,4 +31,13 @@ $modsForHesk_settings['html_emails'] = 1; //-- Mailgun Settings $modsForHesk_settings['use_mailgun'] = 0; $modsForHesk_settings['mailgun_api_key'] = ''; -$modsForHesk_settings['mailgun_domain'] = ''; \ No newline at end of file +$modsForHesk_settings['mailgun_domain'] = ''; + +//-- Set this to 1 to enable bootstrap-theme.css +$modsForHesk_settings['use_bootstrap_theme'] = 1; + +//-- Default value for new Knowledgebase article: 0 = Published, 1 = Private, 2 = Draft +$modsForHesk_settings['new_kb_article_visibility'] = 0; + +//-- Setting for adding attachments to email messages. Either 0 for default-HESK behavior, or 1 to send as attachments +$modsForHesk_settings['attachments'] = 0; \ No newline at end of file diff --git a/print.php b/print.php index a9044d83..d4d26795 100644 --- a/print.php +++ b/print.php @@ -1,7 +1,7 @@ :

    -

    '.$hesklang['open_action'].'';} - elseif ($hesk_settings['custclose']) {echo ''.$hesklang['close_action'].'';} ?>

    +

    '.$hesklang['open_action'].''; + } + elseif ($hesk_settings['custclose'] && $isClosable) { + echo ''.$hesklang['close_action'].''; + } ?>

    @@ -468,7 +476,7 @@ function print_form()
    - +
    - +
    @@ -509,7 +517,7 @@ function print_form()
    - +
    diff --git a/verifyemail.php b/verifyemail.php index a77999e7..c6ac2cea 100644 --- a/verifyemail.php +++ b/verifyemail.php @@ -109,7 +109,7 @@ require_once(HESK_PATH . 'inc/header.inc.php');
    - +