@@ -117,7 +129,8 @@ class AdminPanelCustomResponses extends React.Component {
values: this.state.form,
errors: this.state.errors,
loading: this.state.formLoading,
- onChange: (form) => {this.setState({form, edited: true})},
+ onClick: () => this.setState({formClicked: true}),
+ onChange: (form) => this.setState({form}),
onValidateErrors: (errors) => {this.setState({errors})},
onSubmit: this.onFormSubmit.bind(this)
}
@@ -139,7 +152,7 @@ class AdminPanelCustomResponses extends React.Component {
}
onItemChange(index) {
- if(this.state.edited) {
+ if(this.isEdited()) {
AreYouSure.openModal(i18n('WILL_LOSE_CHANGES'), this.updateForm.bind(this, index));
} else {
this.updateForm(index);
@@ -147,28 +160,30 @@ class AdminPanelCustomResponses extends React.Component {
}
onFormSubmit(form) {
+ const {items, allowedLanguages} = this.props;
this.setState({formLoading: true});
if(this.state.selectedIndex !== -1) {
API.call({
path: '/ticket/edit-custom-response',
data: {
- id: this.props.items[this.state.selectedIndex].id,
- name: form.name,
+ id: items[this.state.selectedIndex].id,
+ name: form.title,
content: form.content,
- language: form.language
+ language: _.includes(allowedLanguages, form.language) ? form.language : allowedLanguages[0]
}
}).then(() => {
- this.setState({formLoading: false});
+ this.setState({formLoading: false, originalForm: form});
this.retrieveCustomResponses();
}).catch(this.onItemChange.bind(this, -1));
} else {
+ this.setState({form, originalForm: form});
API.call({
path: '/ticket/add-custom-response',
data: {
name: form.title,
content: form.content,
- language: form.language
+ language: _.includes(allowedLanguages, form.language) ? form.language : allowedLanguages[0]
}
}).then(() => {
this.retrieveCustomResponses();
@@ -204,12 +219,14 @@ class AdminPanelCustomResponses extends React.Component {
form.title = (this.props.items[index] && this.props.items[index].name) || '';
form.content = TextEditor.getEditorStateFromHTML((this.props.items[index] && this.props.items[index].content) || '');
- form.language = (this.props.items[index] && this.props.items[index].language) || 'en';
+ form.language = (this.props.items[index] && this.props.items[index].language) || this.props.language;
this.setState({
+ formClicked: false,
+ showForm: true,
selectedIndex: index,
- edited: false,
formLoading: false,
+ originalForm: form,
form: form,
errors: {}
});
@@ -217,14 +234,21 @@ class AdminPanelCustomResponses extends React.Component {
retrieveCustomResponses() {
this.props.dispatch(AdminDataActions.retrieveCustomResponses());
- this.setState({
- edited: false
- });
+ }
+
+ isEdited() {
+ return this.state.form.title && this.state.formClicked && (
+ this.state.form.title != this.state.originalForm.title ||
+ this.state.form.content != this.state.originalForm.content ||
+ this.state.form.language != this.state.originalForm.language
+ );
}
}
export default connect((store) => {
return {
+ allowedLanguages: store.config.allowedLanguages,
+ language: store.config.language,
loaded: store.adminData.customResponsesLoaded,
items: store.adminData.customResponses
};
diff --git a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js
index 2b85418b..8a07c702 100644
--- a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js
+++ b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js
@@ -18,11 +18,17 @@ class AdminPanelMyTickets extends React.Component {
static defaultProps = {
userId: 0,
departments: [],
- tickets: []
+ tickets: [],
+ page: 1,
+ pages: 0,
+ };
+
+ state = {
+ closedTicketsShown: false,
};
componentDidMount() {
- this.props.dispatch(AdminDataAction.retrieveMyTickets());
+ this.retrieveMyTickets()
}
render() {
@@ -46,10 +52,23 @@ class AdminPanelMyTickets extends React.Component {
tickets: this.props.tickets,
type: 'secondary',
loading: this.props.loading,
- ticketPath: '/admin/panel/tickets/view-ticket/'
+ ticketPath: '/admin/panel/tickets/view-ticket/',
+ closedTicketsShown: this.state.closedTicketsShown,
+ onClosedTicketsShownChange: this.onClosedTicketsShownChange.bind(this),
+ pages: this.props.pages,
+ page: this.props.page,
+ onPageChange: event => this.retrieveMyTickets(event.target.value)
};
}
+ onClosedTicketsShownChange() {
+ this.setState(function(state) {
+ return {
+ closedTicketsShown: !state.closedTicketsShown
+ };
+ }, () => this.retrieveMyTickets());
+ }
+
onCreateTicket() {
ModalContainer.openModal(
@@ -63,7 +82,11 @@ class AdminPanelMyTickets extends React.Component {
onCreateTicketSuccess() {
ModalContainer.closeModal();
- this.props.dispatch(AdminDataAction.retrieveMyTickets());
+ this.retrieveMyTickets();
+ }
+
+ retrieveMyTickets(page = this.props.page, closed = this.state.closedTicketsShown) {
+ this.props.dispatch(AdminDataAction.retrieveMyTickets(page, closed * 1));
}
}
@@ -72,6 +95,8 @@ export default connect((store) => {
userId: store.session.userId,
departments: store.session.userDepartments,
tickets: store.adminData.myTickets,
+ page: store.adminData.myTicketsPage,
+ pages: store.adminData.myTicketsPages,
loading: !store.adminData.myTicketsLoaded,
error: store.adminData.myTicketsError
};
diff --git a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js
index 86b5e5be..7f0f2ccb 100644
--- a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js
+++ b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js
@@ -12,13 +12,14 @@ import Message from 'core-components/message';
class AdminPanelNewTickets extends React.Component {
static defaultProps = {
+ page: 1,
userId: 0,
departments: [],
tickets: []
};
componentDidMount() {
- this.props.dispatch(AdminDataAction.retrieveNewTickets());
+ this.retrieveNewTickets();
}
render() {
@@ -39,9 +40,16 @@ class AdminPanelNewTickets extends React.Component {
tickets: this.props.tickets,
type: 'secondary',
loading: this.props.loading,
- ticketPath: '/admin/panel/tickets/view-ticket/'
+ ticketPath: '/admin/panel/tickets/view-ticket/',
+ page: this.props.page,
+ pages: this.props.pages,
+ onPageChange: event => this.retrieveNewTickets(event.target.value)
};
}
+
+ retrieveNewTickets(page = this.props.page) {
+ this.props.dispatch(AdminDataAction.retrieveNewTickets(page));
+ }
}
export default connect((store) => {
@@ -49,6 +57,8 @@ export default connect((store) => {
userId: store.session.userId,
departments: store.session.userDepartments,
tickets: store.adminData.newTickets,
+ page: store.adminData.newTicketsPage,
+ pages: store.adminData.newTicketsPages,
loading: !store.adminData.newTicketsLoaded,
error: store.adminData.newTicketsError
};
diff --git a/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js b/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js
index 54378546..57e50d6c 100644
--- a/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js
+++ b/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js
@@ -34,7 +34,6 @@ class DashboardCreateTicketPage extends React.Component {
onCreateTicketSuccess() {
if((this.props.location.pathname !== '/create-ticket')) {
- this.props.dispatch(SessionActions.getUserData());
setTimeout(() => {history.push('/dashboard')}, 2000);
} else {
setTimeout(() => {history.push('/check-ticket/' + result.data.ticketNumber + '/' + email)}, 1000);
diff --git a/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js b/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js
index 1623df49..352dbe40 100644
--- a/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js
+++ b/client/src/app/main/dashboard/dashboard-list-tickets/dashboard-list-tickets-page.js
@@ -1,6 +1,8 @@
import React from 'react';
import {connect} from 'react-redux';
+import SessionActions from 'actions/session-actions';
+
import i18n from 'lib-app/i18n';
import Header from 'core-components/header';
@@ -15,6 +17,10 @@ class DashboardListTicketsPage extends React.Component {
tickets: []
};
+ componentDidMount() {
+ this.retrieveUserData();
+ }
+
render() {
return (
@@ -23,6 +29,10 @@ class DashboardListTicketsPage extends React.Component {
);
}
+
+ retrieveUserData() {
+ this.props.dispatch(SessionActions.getUserData());
+ }
}
diff --git a/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js b/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js
index 4f30814d..1af40be3 100644
--- a/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js
+++ b/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.js
@@ -1,59 +1,82 @@
import React from 'react';
import _ from 'lodash';
-import {connect} from 'react-redux';
+
+import store from 'app/store';
+import SessionActions from 'actions/session-actions';
import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call';
-import SessionActions from 'actions/session-actions';
import TicketViewer from 'app-components/ticket-viewer';
+import Loading from 'core-components/loading';
+import Message from 'core-components/message';
class DashboardTicketPage extends React.Component {
- static propTypes = {
- tickets: React.PropTypes.array
+ state = {
+ error: null,
+ ticket: null,
};
componentDidMount() {
- let ticket = this.getTicketData();
-
- if(ticket.unread) {
- API.call({
- path: '/ticket/seen',
- data: {
- ticketNumber: ticket.ticketNumber
- }
- }).then(() => {
- this.retrieveUserData();
- });
- }
+ this.retrieveTicketData();
}
render() {
- let ticketView = i18n('NO_PERMISSION');
-
- if(!_.isEmpty(this.getTicketData())) {
- ticketView =
;
- }
+ const {ticket, error} = this.state;
return (
- {ticketView}
+ {(ticket || error) ? this.renderContent() : }
);
}
- getTicketData() {
- return _.find(this.props.tickets, {ticketNumber: this.props.params.ticketNumber}) || {};
+ renderContent() {
+ const {ticket, error} = this.state;
+
+ if(error) {
+ return (
+
+ {i18n(error)}
+
+ );
+ } else {
+ return (
+
+ );
+ }
+
+ }
+
+ retrieveTicketData() {
+ API.call({
+ path: '/ticket/get',
+ data: {
+ ticketNumber: this.props.params.ticketNumber,
+ }
+ })
+ .then(result => {
+ const ticket = result.data
+ this.setState({ticket, error: null})
+
+ if(ticket.unread) {
+ API.call({
+ path: '/ticket/seen',
+ data: {
+ ticketNumber: ticket.ticketNumber
+ }
+ }).then(() => {
+ this.retrieveUserData();
+ });
+ }
+ })
+ .catch(result => this.setState({error: result.message}));
}
retrieveUserData() {
- this.props.dispatch(SessionActions.getUserData());
+ store.dispatch(SessionActions.getUserData());
}
}
-export default connect((store) => {
- return {
- tickets: store.session.userTickets
- };
-})(DashboardTicketPage);
+export default DashboardTicketPage;
diff --git a/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.scss b/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.scss
index 4caad9b2..3a16b2c2 100644
--- a/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.scss
+++ b/client/src/app/main/dashboard/dashboard-ticket/dashboard-ticket-page.scss
@@ -1,3 +1,7 @@
.dashboard-ticket-page {
padding: 0 10px;
-}
\ No newline at end of file
+
+ &__loading {
+ min-height: 300px;
+ }
+}
diff --git a/client/src/core-components/form-field.scss b/client/src/core-components/form-field.scss
index 28a3d6df..4629ee9a 100644
--- a/client/src/core-components/form-field.scss
+++ b/client/src/core-components/form-field.scss
@@ -45,4 +45,4 @@
padding-bottom: 10px;
}
}
-}
\ No newline at end of file
+}
diff --git a/client/src/data/languages/br.js b/client/src/data/languages/br.js
index d8702d58..4d77900a 100644
--- a/client/src/data/languages/br.js
+++ b/client/src/data/languages/br.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Chave Pública do Recaptcha',
'RECAPTCHA_PRIVATE_KEY': 'Private Key do Recaptcha',
'ALLOW_FILE_ATTACHMENTS': 'Permitir anexar arquivos',
- 'MAX_SIZE_KB': 'Tamanho máximo (KB)',
+ 'MAX_SIZE_MB': 'Tamanho máximo (MB)',
'UPDATE_SETTINGS': 'Atualizar configurações',
'DEFAULT_LANGUAGE': 'Idioma padrão',
'SUPPORTED_LANGUAGES': 'Idiomas suportados',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Inicio',
'TICKET_NUMBER': 'Número do chamado',
'NEXT': 'Próximo',
+ 'SUBJECT': 'Sujeito',
'SEND_EMAIL_ON_NEW_TICKET': 'Enviar email para cada novo ticket',
'STAFF_UPDATED': 'Membro da equipe atualizado',
'UPDATE': 'Atualizar',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'privado',
'ENABLE_USER': 'Ativar usuário',
'DISABLE_USER': 'Desativar usuário',
+ 'SHOW_CLOSED_TICKETS': 'Mostrar ingressos fechados',
+ 'IMAGE_HEADER_URL': 'URL do cabeçalho da imagem',
'CHART_CREATE_TICKET': 'Chamados criados',
'CHART_CLOSE': 'Chamados fechados',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Erros encontrados',
'ERROR_IMAGE_SIZE': 'Nenhuma imagem pode ter um tamanho maior que {size} MB',
'USER_DISABLED': 'Esta conta está desativada.',
+ 'INVALID_SYNTAX': 'Sintaxe inválida.',
//MESSAGES
'SIGNUP_SUCCESS': 'Você se registrou com sucesso em nosso sistema de suporte.',
diff --git a/client/src/data/languages/cn.js b/client/src/data/languages/cn.js
index 1e419142..c0fa15ef 100644
--- a/client/src/data/languages/cn.js
+++ b/client/src/data/languages/cn.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha公鑰',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha私人鑰匙',
'ALLOW_FILE_ATTACHMENTS': '允許文件附件',
- 'MAX_SIZE_KB': '最大尺寸(KB)',
+ 'MAX_SIZE_MB': '最大尺寸(KB)',
'UPDATE_SETTINGS': '更新設置',
'DEFAULT_LANGUAGE': '默認語言',
'SUPPORTED_LANGUAGES': '支持的語言',
@@ -178,6 +178,7 @@ export default {
'HOME': '家',
'TICKET_NUMBER': '票號',
'NEXT': '下一個',
+ 'SUBJECT': '学科',
'SEND_EMAIL_ON_NEW_TICKET': '电子邮件为每个新票',
'STAFF_UPDATED': '工作人员已更新',
'UPDATE': '更新',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': '私人的',
'ENABLE_USER': '启用用户',
'DISABLE_USER': '禁用用户',
+ 'SHOW_CLOSED_TICKETS': '显示已关闭的门票',
+ 'IMAGE_HEADER_URL': '图片标题网址',
'CHART_CREATE_TICKET': '已創建門票',
'CHART_CLOSE': '門票已關閉',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': '發現錯誤',
'ERROR_IMAGE_SIZE': '没有图像的大小可以超过{size}MB',
'USER_DISABLED': '此帐户已被停用。',
+ 'INVALID_SYNTAX': '无效的语法。',
//MESSAGES
'SIGNUP_SUCCESS': '您已在我們的支持系統中成功註冊',
diff --git a/client/src/data/languages/de.js b/client/src/data/languages/de.js
index f82747c4..9c92e990 100644
--- a/client/src/data/languages/de.js
+++ b/client/src/data/languages/de.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha - Öffentlicher Schlüssel',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha - Privater Schlüssel',
'ALLOW_FILE_ATTACHMENTS': 'Dateianlagen zulassen',
- 'MAX_SIZE_KB': 'Max. Größe (KB)',
+ 'MAX_SIZE_MB': 'Max. Größe (MB)',
'UPDATE_SETTINGS': 'Einstellungen aktualisieren',
'DEFAULT_LANGUAGE': 'Standardsprache',
'SUPPORTED_LANGUAGES': 'Unterstützte Sprachen',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Home',
'TICKET_NUMBER': 'Ticketnummer',
'NEXT': 'Nächstes',
+ 'SUBJECT': 'Gegenstand',
'SEND_EMAIL_ON_NEW_TICKET': 'E-Mail für jedes neues Ticket',
'STAFF_UPDATED': 'Mitarbeiter wurde aktualisiert',
'UPDATE': 'Aktualisierung',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'Privatgelände',
'ENABLE_USER': 'Benutzer aktivieren',
'DISABLE_USER': 'Benutzer deaktivieren',
+ 'SHOW_CLOSED_TICKETS': 'Geschlossene Tickets anzeigen',
+ 'IMAGE_HEADER_URL': 'URL des Image-Headers',
'CHART_CREATE_TICKET': 'Tickets erstellt',
'CHART_CLOSE': 'Tickets geschlossen',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Fehler gefunden!',
'ERROR_IMAGE_SIZE': 'Kein Bild darf größer als {size} MB sein',
'USER_DISABLED': 'Dieser Account ist deaktiviert.',
+ 'INVALID_SYNTAX': 'Ungültiger Satzbau.',
//MESSAGES
'SIGNUP_SUCCESS': 'Sie haben sich erfolgreich in unserem Support-System registriert.',
diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js
index 58df9540..02a11596 100644
--- a/client/src/data/languages/en.js
+++ b/client/src/data/languages/en.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha Public Key',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Private Key',
'ALLOW_FILE_ATTACHMENTS': 'Allow file attachments',
- 'MAX_SIZE_KB': 'Max Size (KB)',
+ 'MAX_SIZE_MB': 'Max Size (MB)',
'UPDATE_SETTINGS': 'Update settings',
'DEFAULT_LANGUAGE': 'Default Language',
'SUPPORTED_LANGUAGES': 'Supported Languages',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Home',
'TICKET_NUMBER': 'Ticket number',
'NEXT': 'Next',
+ 'SUBJECT': 'Subject',
'SEND_EMAIL_ON_NEW_TICKET': 'Send email on new ticket',
'STAFF_UPDATED': 'Staff member has been updated',
'UPDATE': 'Update',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'Private',
'ENABLE_USER': 'Enable User',
'DISABLE_USER': 'Disable User',
+ 'SHOW_CLOSED_TICKETS': 'Show Closed Tickets',
+ 'IMAGE_HEADER_URL': 'Image header URL',
'CHART_CREATE_TICKET': 'Tickets created',
'CHART_CLOSE': 'Tickets closed',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Errors found',
'ERROR_IMAGE_SIZE': 'No image can have a size greater than {size} MB',
'USER_DISABLED': 'This account is disabled.',
+ 'INVALID_SYNTAX': 'Invalid syntax.',
//MESSAGES
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',
diff --git a/client/src/data/languages/es.js b/client/src/data/languages/es.js
index 59addec6..4b9c5ef4 100644
--- a/client/src/data/languages/es.js
+++ b/client/src/data/languages/es.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha clave pública',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha clave privada',
'ALLOW_FILE_ATTACHMENTS': 'Permitir archivos adjuntos',
- 'MAX_SIZE_KB': 'Tamaño máximo (KB)',
+ 'MAX_SIZE_MB': 'Tamaño máximo (MB)',
'UPDATE_SETTINGS': 'Actualizar Configuraciones',
'DEFAULT_LANGUAGE': 'Idioma predeterminado',
'SUPPORTED_LANGUAGES': 'Idiomas Soportados',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Inicio',
'TICKET_NUMBER': 'Número de Ticket',
'NEXT': 'Siguiente',
+ 'SUBJECT': 'Asunto',
'SEND_EMAIL_ON_NEW_TICKET': 'Enviar email por cada nuevo ticket',
'STAFF_UPDATED': 'Miembro de Staff actualizado',
'UPDATE': 'Actualizar',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'privado',
'ENABLE_USER': 'Habilitar usuario',
'DISABLE_USER': 'Deshabilitar usuario',
+ 'SHOW_CLOSED_TICKETS': 'Mostrar Tickets Cerrados',
+ 'IMAGE_HEADER_URL': 'URL del encabezado de la imagen',
'CHART_CREATE_TICKET': 'Tickets creados',
'CHART_CLOSE': 'Tickets cerrados',
@@ -331,6 +334,8 @@ export default {
'INVALID_EMAIL_OR_TICKET_NUMBER': 'Email o numero de ticket inválido',
'INVALID_FILE': 'Archivo inválido',
'ERRORS_FOUND': 'Se encontraron errores',
+ 'USER_DISABLED': 'Esta cuenta está deshabilitada.',
+ 'INVALID_SYNTAX': 'Sintaxis inválida.',
//MESSAGES
'SIGNUP_SUCCESS': 'Se ha registrado con éxito en nuestro sistema de soporte.',
@@ -357,7 +362,6 @@ export default {
'SUCCESS_IMPORTING_CSV_DESCRIPTION': 'El archivo CSV se ha importado correctamente',
'SUCCESS_DELETING_ALL_USERS': 'Los usuarios se han eliminado correctamente',
'ERROR_IMAGE_SIZE': 'Ninguna imagen puede tener un tamaño superior a {size} MB',
- 'USER_DISABLED': 'Esta cuenta está deshabilitada.',
'LAST_7_DAYS': 'Últimos 7 dias',
'LAST_30_DAYS': 'Últimos 30 dias',
diff --git a/client/src/data/languages/fr.js b/client/src/data/languages/fr.js
index 4b5a7d39..a6eb93f5 100644
--- a/client/src/data/languages/fr.js
+++ b/client/src/data/languages/fr.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Clé publique Recaptcha',
'RECAPTCHA_PRIVATE_KEY': 'Clé privée Recaptcha',
'ALLOW_FILE_ATTACHMENTS': 'Autoriser les pièces jointes',
- 'MAX_SIZE_KB': 'Taille Maximale (Ko)',
+ 'MAX_SIZE_MB': 'Taille Maximale (Ko)',
'UPDATE_SETTINGS': 'Mettre à jour les paramètres',
'DEFAULT_LANGUAGE': 'Langue par défaut',
'SUPPORTED_LANGUAGES': 'Langues prises en charges',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Accueil',
'TICKET_NUMBER': 'Numéro de ticket',
'NEXT': 'Suivant',
+ 'SUBJECT': 'Assujettir',
'SEND_EMAIL_ON_NEW_TICKET': 'Envoyer un e-mail pour chaque nouveau ticket',
'STAFF_UPDATED': 'Le membre du personnel a été mis à jour',
'UPDATE': 'Mettre à jour',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'privé',
'ENABLE_USER': 'Activer l\'utilisateur',
'DISABLE_USER': 'Désactiver l\'utilisateur',
+ 'SHOW_CLOSED_TICKETS': 'Afficher les billets fermés',
+ 'IMAGE_HEADER_URL': 'URL de l\'en-tête de l\'image',
'CHART_CREATE_TICKET': 'Tickets créés',
'CHART_CLOSE': 'Tickets fermés',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Des erreurs sont survenues',
'ERROR_IMAGE_SIZE': 'Aucune image ne peut avoir une taille supérieure à {size} MB',
'USER_DISABLED': 'Ce compte est désactivé.',
+ 'INVALID_SYNTAX': 'Syntaxe invalide.',
//MESSAGES
'SIGNUP_SUCCESS': 'Vous êtes inscrit avec succès dans notre système de support.',
diff --git a/client/src/data/languages/gr.js b/client/src/data/languages/gr.js
index 94b2db28..eaf61c54 100644
--- a/client/src/data/languages/gr.js
+++ b/client/src/data/languages/gr.js
@@ -145,7 +145,7 @@
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha Δημοσίου Κλειδιού',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Ιδιωτικού Κλειδιού',
'ALLOW_FILE_ATTACHMENTS': 'Επιτρέπονται Συνημμένα Αρχεία',
- 'MAX_SIZE_KB': 'Μέγιστο Μέγεθος (KB)',
+ 'MAX_SIZE_MB': 'Μέγιστο Μέγεθος (MB)',
'UPDATE_SETTINGS': 'Ενημέρωση Ρυθμίσεων',
'DEFAULT_LANGUAGE': 'Προεπιλεγμένες Γλώσσες',
'SUPPORTED_LANGUAGES': 'Υποστηριζόμενες Γλώσσες',
@@ -178,6 +178,7 @@
'HOME': 'Σπίτι',
'TICKET_NUMBER': 'Αριθμός εισιτηρίου',
'NEXT': 'Επόμενο',
+ 'SUBJECT': 'Θέμα',
'SEND_EMAIL_ON_NEW_TICKET': 'Στείλτε μήνυμα ηλκετορνικού ταχυδρομείου στο νέο εισιτήριο',
'STAFF_UPDATED': 'Το μέλος προσωπικού έχει ενημερωθεί',
'UPDATE': 'Ενημέρωση',
@@ -188,6 +189,8 @@
'PRIVATE': 'ιδιωτικός',
'ENABLE_USER': 'Ενεργοποίηση χρήστη',
'DISABLE_USER': 'Απενεργοποίηση χρήστη',
+ 'SHOW_CLOSED_TICKETS': 'Εμφάνιση κλειστών εισιτηρίων',
+ 'IMAGE_HEADER_URL': 'Διεύθυνση URL κεφαλίδας εικόνας',
'CHART_CREATE_TICKET': 'Τα εισιτήρια δημιουργήθηκαν',
'CHART_CLOSE': 'Τα εισιτήρια κλείσανε',
@@ -333,6 +336,7 @@
'ERRORS_FOUND': 'Βρέθηκαν Σφάλματα',
'ERROR_IMAGE_SIZE': 'Καμία εικόνα δεν μπορεί να έχει μέγεθος μεγαλύτερο από {size} MB',
'USER_DISABLED': 'Αυτός ο λογαριασμός είναι απενεργοποιημένος.',
+ 'INVALID_SYNTAX': 'Μη έγκυρη σύνταξη.',
//MESSAGES
'SIGNUP_SUCCESS': 'Έχετε εγγραφεί με επιτυχία στο σύστημα υποστήριξης μας.',
diff --git a/client/src/data/languages/in.js b/client/src/data/languages/in.js
index 7f81cfb1..25da03ee 100644
--- a/client/src/data/languages/in.js
+++ b/client/src/data/languages/in.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha सार्वजनिक कुंजी',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha निजी कुंजी',
'ALLOW_FILE_ATTACHMENTS': 'फ़ाइल अनुलग्नकों की अनुमति दें',
- 'MAX_SIZE_KB': 'अधिकतम आकार (KB)',
+ 'MAX_SIZE_MB': 'अधिकतम आकार (MB)',
'UPDATE_SETTINGS': 'सेटिंग अपडेट करें',
'DEFAULT_LANGUAGE': 'डिफ़ॉल्ट भाषा',
'SUPPORTED_LANGUAGES': 'समर्थित भाषाएँ',
@@ -178,6 +178,7 @@ export default {
'HOME': 'घर',
'TICKET_NUMBER': 'टिकट नंबर',
'NEXT': 'आगामी',
+ 'SUBJECT': 'विषय',
'SEND_EMAIL_ON_NEW_TICKET': 'एक ईमेल भेजने के लिए प्रत्येक नए टिकट',
'STAFF_UPDATED': 'स्टाफ सदस्य को अद्यतन किया गया है',
'UPDATE': 'अद्यतन',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'निजी',
'ENABLE_USER': 'उपयोगकर्ता सक्षम करें',
'DISABLE_USER': 'उपयोगकर्ता को अक्षम करें',
+ 'SHOW_CLOSED_TICKETS': 'बंद टिकट दिखाएं',
+ 'IMAGE_HEADER_URL': 'छवि शीर्षलेख यूआरएल',
'CHART_CREATE_TICKET': 'टिकट बनाया',
'CHART_CLOSE': 'टिकट बंद कर दिया',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'त्रुटियां मिलीं',
'ERROR_IMAGE_SIZE': 'कोई छवि {size} एमबी से अधिक आकार नहीं हो सकती है',
'USER_DISABLED': 'यह खाता अक्षम है।',
+ 'INVALID_SYNTAX': 'अवैध वाक्य रचना।',
//MESSAGES
'SIGNUP_SUCCESS': 'आप हमारे समर्थन प्रणाली में सफलतापूर्वक दर्ज कर लिया है।',
diff --git a/client/src/data/languages/it.js b/client/src/data/languages/it.js
index caa00841..c7ca1d7e 100644
--- a/client/src/data/languages/it.js
+++ b/client/src/data/languages/it.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha Public Key',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Private Key',
'ALLOW_FILE_ATTACHMENTS': 'Consenti di allegare file',
- 'MAX_SIZE_KB': 'Dimensione massima (KB)',
+ 'MAX_SIZE_MB': 'Dimensione massima (MB)',
'UPDATE_SETTINGS': 'Aggiorna modifiche',
'DEFAULT_LANGUAGE': 'Lingua predefinita',
'SUPPORTED_LANGUAGES': 'Lingue supportate',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Home',
'TICKET_NUMBER': 'Ticket numero',
'NEXT': 'Prossimo',
+ 'SUBJECT': 'Soggetto',
'SEND_EMAIL_ON_NEW_TICKET': 'Invia e-mail al nuovo ticket',
'STAFF_UPDATED': 'Il membro del personale è stato aggiornato',
'UPDATE': 'Aggiornare',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'privato',
'ENABLE_USER': 'Abilita utente',
'DISABLE_USER': 'Disabilita utente',
+ 'SHOW_CLOSED_TICKETS': 'Mostra biglietti chiusi',
+ 'IMAGE_HEADER_URL': 'URL dell\'intestazione dell\'immagine',
'CHART_CREATE_TICKET': 'Tickets creato',
'CHART_CLOSE': 'Tickets chiuso',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Trovati errori',
'ERROR_IMAGE_SIZE': 'Nessuna immagine può avere una dimensione superiore a {size} MB',
'USER_DISABLED': 'Questo account è disabilitato.',
+ 'INVALID_SYNTAX': 'Sintassi non valida.',
//MESSAGES
'SIGNUP_SUCCESS': 'È stato registrato con successo nel nostro sistema di supporto.',
diff --git a/client/src/data/languages/jp.js b/client/src/data/languages/jp.js
index 1c52c9f1..7c9e63b3 100644
--- a/client/src/data/languages/jp.js
+++ b/client/src/data/languages/jp.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha公開鍵',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha秘密鍵',
'ALLOW_FILE_ATTACHMENTS': '添付ファイルを許可する',
- 'MAX_SIZE_KB': '最大サイズ(KB)',
+ 'MAX_SIZE_MB': '最大サイズ(KB)',
'UPDATE_SETTINGS': '設定を更新する',
'DEFAULT_LANGUAGE': '既定の言語',
'SUPPORTED_LANGUAGES': 'サポートされている言語',
@@ -178,6 +178,7 @@ export default {
'HOME': 'ホーム',
'TICKET_NUMBER': 'チケット番号',
'NEXT': '次',
+ 'SUBJECT': '件名',
'SEND_EMAIL_ON_NEW_TICKET': 'メールを送信毎に新しいチケット',
'STAFF_UPDATED': 'スタッフメンバーが更新されました',
'UPDATE': '更新',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'プライベート',
'ENABLE_USER': 'ユーザーを有効にする',
'DISABLE_USER': 'ユーザーを無効にする',
+ 'SHOW_CLOSED_TICKETS': 'クローズドチケットを表示する',
+ 'IMAGE_HEADER_URL': '画像のヘッダーURL',
'CHART_CREATE_TICKET': '作成されたチケット',
'CHART_CLOSE': 'チケットが閉じられました',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'エラーが見つかりました',
'ERROR_IMAGE_SIZE': 'イメージのサイズが{size} MBを超えることはできません',
'USER_DISABLED': 'このアカウントは無効です。',
+ 'INVALID_SYNTAX': '無効な構文。',
//MESSAGES
'SIGNUP_SUCCESS': 'あなたは私たちのサポートシステムに正常に登録しました。',
diff --git a/client/src/data/languages/nl.js b/client/src/data/languages/nl.js
index e47ab33f..87bff429 100644
--- a/client/src/data/languages/nl.js
+++ b/client/src/data/languages/nl.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha Publieke Sleutel',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Prive Sleutel',
'ALLOW_FILE_ATTACHMENTS': 'Sta bijlage(s) toe',
- 'MAX_SIZE_KB': 'Max grootte (KB)',
+ 'MAX_SIZE_MB': 'Max grootte (MB)',
'UPDATE_SETTINGS': 'Update instellingen',
'DEFAULT_LANGUAGE': 'Standaard Taal',
'SUPPORTED_LANGUAGES': 'Talen die zijn ondersteund',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Home',
'TICKET_NUMBER': 'Incidentnummer',
'NEXT': 'Volgende',
+ 'SUBJECT': 'Bedrijf',
'SEND_EMAIL_ON_NEW_TICKET': 'Stuur e-mail bij nieuw incident',
'STAFF_UPDATED': 'Medewerker is gewijzigd',
'UPDATE': 'Update',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'privaat',
'ENABLE_USER': 'Schakel gebruiker in',
'DISABLE_USER': 'Gebruiker uitschakelen',
+ 'SHOW_CLOSED_TICKETS': 'Toon gesloten tickets',
+ 'IMAGE_HEADER_URL': 'Image header URL',
'CHART_CREATE_TICKET': 'Aangemaakte incidenten',
'CHART_CLOSE': 'Gesloten incidenten',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Er is een fout opgetreden',
'ERROR_IMAGE_SIZE': 'Geen enkele afbeelding kan groter zijn dan {size} MB',
'USER_DISABLED': 'Dit account is uitgeschakeld.',
+ 'INVALID_SYNTAX': 'Ongeldige syntaxis.',
//MESSAGES
'SIGNUP_SUCCESS': 'U hebt zich succesvol geregistreerd in ons ondersteuningssysteem.',
diff --git a/client/src/data/languages/pt.js b/client/src/data/languages/pt.js
index d1db214f..a4d6aeac 100644
--- a/client/src/data/languages/pt.js
+++ b/client/src/data/languages/pt.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha Chave Pública',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Private Key',
'ALLOW_FILE_ATTACHMENTS': 'Permitir anexos de arquivo',
- 'MAX_SIZE_KB': 'Tamanho máximo (KB)',
+ 'MAX_SIZE_MB': 'Tamanho máximo (MB)',
'UPDATE_SETTINGS': 'Atualizar configurações',
'DEFAULT_LANGUAGE': 'Idioma padrão',
'SUPPORTED_LANGUAGES': 'Idiomas suportados',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Casa',
'TICKET_NUMBER': 'Número do bilhete',
'NEXT': 'Próximo',
+ 'SUBJECT': 'Sujeito',
'SEND_EMAIL_ON_NEW_TICKET': 'Enviar email para cada novo ticket',
'STAFF_UPDATED': 'Membro da equipe foi atualizado',
'UPDATE': 'Actualizar',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'privado',
'ENABLE_USER': 'Ativar usuário',
'DISABLE_USER': 'Desativar usuário',
+ 'SHOW_CLOSED_TICKETS': 'Mostrar ingressos fechados',
+ 'IMAGE_HEADER_URL': 'URL do cabeçalho da imagem',
'CHART_CREATE_TICKET': 'Ingressos criados',
'CHART_CLOSE': 'Ingressos fechados',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Erros encontrados',
'ERROR_IMAGE_SIZE': 'Nenhuma imagem pode ter um tamanho maior que {size} MB',
'USER_DISABLED': 'Esta conta está desativada.',
+ 'INVALID_SYNTAX': 'Sintaxe inválida.',
//MESSAGES
'SIGNUP_SUCCESS': 'Você se registrou com sucesso em nosso sistema de suporte.',
diff --git a/client/src/data/languages/ru.js b/client/src/data/languages/ru.js
index c967a393..33331250 100644
--- a/client/src/data/languages/ru.js
+++ b/client/src/data/languages/ru.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Recaptcha Открытый ключ',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Секретный ключ',
'ALLOW_FILE_ATTACHMENTS': 'Разрешить файловые вложения',
- 'MAX_SIZE_KB': 'Максимальный размер (КБ)',
+ 'MAX_SIZE_MB': 'Максимальный размер (КБ)',
'UPDATE_SETTINGS': 'Обновить настройки',
'DEFAULT_LANGUAGE': 'Язык по умолчанию',
'SUPPORTED_LANGUAGES': 'Поддерживаемые Языки',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Главная',
'TICKET_NUMBER': 'Номер билета',
'NEXT': 'следующий',
+ 'SUBJECT': 'Предмет',
'SEND_EMAIL_ON_NEW_TICKET': 'Отправить письмо на новый билет',
'STAFF_UPDATED': 'Сотрудник обновлен',
'UPDATE': 'Обновить',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'частный',
'ENABLE_USER': 'Включить пользователя',
'DISABLE_USER': 'Отключить пользователя',
+ 'SHOW_CLOSED_TICKETS': 'Показать закрытые билеты',
+ 'IMAGE_HEADER_URL': 'URL заголовка изображения',
'CHART_CREATE_TICKET': 'Билеты создано',
'CHART_CLOSE': ' Билеты закрыты',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Ошибки найдены',
'ERROR_IMAGE_SIZE': 'Изображение не может иметь размер больше {size} МБ',
'USER_DISABLED': 'Эта учетная запись отключена.',
+ 'INVALID_SYNTAX': 'Недопустимый синтаксис.',
//MESSAGES
'SIGNUP_SUCCESS': 'Вы успешно зарегистрировались в нашей системе поддержки.',
diff --git a/client/src/data/languages/tr.js b/client/src/data/languages/tr.js
index 0a00bf76..16ea1543 100644
--- a/client/src/data/languages/tr.js
+++ b/client/src/data/languages/tr.js
@@ -145,7 +145,7 @@ export default {
'RECAPTCHA_PUBLIC_KEY': 'Hızlı Erişim Anahtarı',
'RECAPTCHA_PRIVATE_KEY': 'Recaptcha Özel Anahtar',
'ALLOW_FILE_ATTACHMENTS': 'Dosya eklerine izin ver',
- 'MAX_SIZE_KB': 'Maksimum Boyut (KB)',
+ 'MAX_SIZE_MB': 'Maksimum Boyut (MB)',
'UPDATE_SETTINGS': 'Ayarları güncelle',
'DEFAULT_LANGUAGE': 'Varsayılan dil',
'SUPPORTED_LANGUAGES': 'Desteklenen Diller',
@@ -178,6 +178,7 @@ export default {
'HOME': 'Ev',
'TICKET_NUMBER': 'Bilet numarası',
'NEXT': 'Sonraki',
+ 'SUBJECT': 'konu',
'SEND_EMAIL_ON_NEW_TICKET': 'Yeni biletle e-posta gönder',
'STAFF_UPDATED': 'Çalışanlar güncellendi',
'UPDATE': 'Güncelleştirme',
@@ -188,6 +189,8 @@ export default {
'PRIVATE': 'gizli',
'ENABLE_USER': 'Kullanıcıyı Etkinleştir',
'DISABLE_USER': 'Kullanıcıyı Devre Dışı Bırak',
+ 'SHOW_CLOSED_TICKETS': 'Kapalı Biletleri Göster',
+ 'IMAGE_HEADER_URL': 'Resim başlığı URL\'si',
'CHART_CREATE_TICKET': 'Biletler oluşturuldu',
'CHART_CLOSE': 'Biletler kapandı',
@@ -333,6 +336,7 @@ export default {
'ERRORS_FOUND': 'Hatalar bulundu',
'ERROR_IMAGE_SIZE': 'Hiçbir resmin boyutu {size} MB\'den büyük olabilir',
'USER_DISABLED': 'Bu hesap devre dışı.',
+ 'INVALID_SYNTAX': 'Geçersiz sözdizimi.',
//MESSAGES
'SIGNUP_SUCCESS': 'Destek sistemimize başarılı bir şekilde kayıt oldunuz.',
diff --git a/client/src/lib-app/mentions-parser.js b/client/src/lib-app/mentions-parser.js
new file mode 100644
index 00000000..81579c57
--- /dev/null
+++ b/client/src/lib-app/mentions-parser.js
@@ -0,0 +1,53 @@
+const PARSING_TEXT = 0;
+const PARSING_MENTION = 1;
+
+class MentionsParser {
+
+ parse(text) {
+ let parsingLink = false;
+ let parsingType = PARSING_TEXT;
+ let parsingSegment = '';
+ let ans = '';
+
+ for(let index = 0; index < text.length; ++index){
+ let character = text[index];
+
+ if(character == '#'){
+ ans += this.compileSegment(parsingSegment, parsingType);
+
+ parsingLink = true;
+ parsingType = PARSING_MENTION;
+ parsingSegment = '';
+ } else if(!this.isAlphanumeric(character) && parsingLink){
+ ans += this.compileSegment(parsingSegment, parsingType);
+
+ parsingLink = false;
+ parsingType = PARSING_TEXT;
+ parsingSegment = character;
+ } else {
+ parsingSegment += character;
+ }
+ }
+
+ ans += this.compileSegment(parsingSegment, parsingType);
+
+ return ans;
+ }
+
+ isAlphanumeric(string){
+ return /[a-zA-Z0-9]/.test(string);
+ }
+
+ compileSegment(segment, parsingType){
+ switch(parsingType){
+ case PARSING_TEXT:
+ return segment;
+ case PARSING_MENTION:
+ return '#' + segment + '';
+ default:
+ return '';
+ }
+ }
+};
+
+export default new MentionsParser;
diff --git a/client/src/reducers/admin-data-reducer.js b/client/src/reducers/admin-data-reducer.js
index 5aa12b2d..abb70499 100644
--- a/client/src/reducers/admin-data-reducer.js
+++ b/client/src/reducers/admin-data-reducer.js
@@ -11,14 +11,20 @@ class AdminDataReducer extends Reducer {
customResponsesLoaded: false,
myTickets: [],
+ myTicketsPage: 1,
+ myTicketsPages: 1,
myTicketsLoaded: false,
myTicketsError: false,
newTickets: [],
+ newTicketsPage: 1,
+ newTicketsPages: 1,
newTicketsLoaded: false,
newTicketsError: false,
allTickets: [],
+ allTicketsPage: 1,
+ allTicketsPages: 1,
allTicketsLoaded: false,
allTicketsError: false,
@@ -61,7 +67,9 @@ class AdminDataReducer extends Reducer {
onMyTicketsRetrieved(state, payload) {
return _.extend({}, state, {
- myTickets: payload.data,
+ myTickets: payload.data.tickets,
+ myTicketsPage: payload.data.page * 1,
+ myTicketsPages: payload.data.pages * 1,
myTicketsLoaded: true
});
}
@@ -82,7 +90,9 @@ class AdminDataReducer extends Reducer {
onNewTicketsRetrieved(state, payload) {
return _.extend({}, state, {
- newTickets: payload.data,
+ newTickets: payload.data.tickets,
+ newTicketsPage: payload.data.page * 1,
+ newTicketsPages: payload.data.pages * 1,
newTicketsLoaded: true
});
}
@@ -104,7 +114,8 @@ class AdminDataReducer extends Reducer {
onAllTicketsRetrieved(state, payload) {
return _.extend({}, state, {
allTickets: payload.data.tickets,
- allTicketsPages: payload.data.pages,
+ allTicketsPage: payload.data.page * 1,
+ allTicketsPages: payload.data.pages * 1,
allTicketsLoaded: true
});
}
diff --git a/client/src/reducers/session-reducer.js b/client/src/reducers/session-reducer.js
index 03ad4797..c3e53f64 100644
--- a/client/src/reducers/session-reducer.js
+++ b/client/src/reducers/session-reducer.js
@@ -103,9 +103,9 @@ class SessionReducer extends Reducer {
onUserDataRetrieved(state, payload) {
let userData = payload.data;
-
+
sessionStore.storeUserData(payload.data);
-
+
return _.extend({}, state, {
staff: userData.staff,
userName: userData.name,
@@ -117,11 +117,11 @@ class SessionReducer extends Reducer {
userSendEmailOnNewTicket: userData.sendEmailOnNewTicket * 1
});
}
-
+
onSessionChecked(state) {
let userData = sessionStore.getUserData();
let userId = sessionStore.getSessionData().userId;
-
+
return _.extend({}, state, {
initDone: true,
logged: true,
@@ -144,4 +144,4 @@ class SessionReducer extends Reducer {
}
}
-export default SessionReducer.getInstance();
\ No newline at end of file
+export default SessionReducer.getInstance();
diff --git a/server/composer.json b/server/composer.json
index 385b094c..48bc8e7b 100755
--- a/server/composer.json
+++ b/server/composer.json
@@ -12,9 +12,7 @@
"require-dev": {
"phpunit/phpunit": "^5.7"
},
- "autoload": {
- "classmap": [
- "libs/SingletonTrait.php"
- ]
+ "autoload":{
+ "classmap": ["libs/", "models/", "controllers/", "data/"]
}
}
diff --git a/server/controllers/article.php b/server/controllers/article.php
index e2079885..6d8b6285 100755
--- a/server/controllers/article.php
+++ b/server/controllers/article.php
@@ -1,12 +1,4 @@
setGroupPath('/article');
diff --git a/server/controllers/staff.php b/server/controllers/staff.php
index 9967e9db..997c5f25 100755
--- a/server/controllers/staff.php
+++ b/server/controllers/staff.php
@@ -1,17 +1,4 @@
setGroupPath('/staff');
diff --git a/server/controllers/staff/get-all-tickets.php b/server/controllers/staff/get-all-tickets.php
index 03d2c8bf..da6dda2b 100755
--- a/server/controllers/staff/get-all-tickets.php
+++ b/server/controllers/staff/get-all-tickets.php
@@ -2,18 +2,20 @@
use Respect\Validation\Validator as DataValidator;
/**
- * @api {post} /staff/get-all-tickets Get all tickets
+ * @api {post} /staff/get-all-tickets Get all tickets according to search
* @apiVersion 4.3.0
*
* @apiName Get all tickets
*
* @apiGroup Staff
*
- * @apiDescription This path retrieves all tickets.
+ * @apiDescription This path retrieves all tickets according to search and opened/closed filters.
*
* @apiPermission staff1
*
* @apiParam {Number} page The page number.
+ * @apiParam {String} query Query string to search.
+ * @apiParam {Boolean} closed Include closed tickets.
*
* @apiUse NO_PERMISSION
* @apiUse INVALID_PAGE
@@ -29,7 +31,7 @@ class GetAllTicketsStaffController extends Controller {
const METHOD = 'POST';
public function validations() {
- return[
+ return [
'permission' => 'staff_1',
'requestData' => [
'page' => [
@@ -50,7 +52,7 @@ class GetAllTicketsStaffController extends Controller {
}
Response::respondSuccess([
- 'tickets' => $this->getTicketList()->toArray(),
+ 'tickets' => $this->getTicketList()->toArray(true),
'pages' => $this->getTotalPages()
]);
}
@@ -58,16 +60,35 @@ class GetAllTicketsStaffController extends Controller {
private function getTicketList() {
$page = Controller::request('page');
- $query = $this->getStaffDepartmentsQueryFilter();
- $query .= 'ORDER BY id DESC LIMIT 10 OFFSET ' . (($page-1)*10);
+ $query = $this->getSearchQuery();
+ $query .= $this->getStaffDepartmentsQueryFilter();
+ $query .= $this->getClosedFilter();
+ $query .= "ORDER BY CASE WHEN (title LIKE ?) THEN 1 ELSE 2 END ASC, id DESC LIMIT 10 OFFSET " . (($page-1)*10);
- return Ticket::find($query);
+ return Ticket::find($query, [
+ Controller::request('query') . '%',
+ '%' . Controller::request('query') . '%',
+ Controller::request('query') . '%'
+ ]);
+ }
+
+ private function getSearchQuery() {
+ $page = Controller::request('page');
+
+ $query = " (title LIKE ? OR title LIKE ?) AND ";
+
+ return $query;
}
private function getTotalPages() {
- $query = $this->getStaffDepartmentsQueryFilter();
+ $query = $this->getSearchQuery();
+ $query .= $this->getStaffDepartmentsQueryFilter();
+ $query .= $this->getClosedFilter();
- return ceil(Ticket::count($query) / 10);
+ return ceil(Ticket::count($query, [
+ Controller::request('query') . '%',
+ '%' . Controller::request('query') . '%'
+ ]) / 10);
}
private function getStaffDepartmentsQueryFilter() {
@@ -81,4 +102,13 @@ class GetAllTicketsStaffController extends Controller {
return $query;
}
+
+ private function getClosedFilter() {
+ $closed = Controller::request('closed')*1;
+ if ($closed) {
+ return '';
+ } else {
+ return " AND (closed = '0')";
+ }
+ }
}
diff --git a/server/controllers/staff/get-new-tickets.php b/server/controllers/staff/get-new-tickets.php
index c342ac11..381ca2a3 100755
--- a/server/controllers/staff/get-new-tickets.php
+++ b/server/controllers/staff/get-new-tickets.php
@@ -14,9 +14,15 @@ use Respect\Validation\Validator as DataValidator;
*
* @apiPermission staff1
*
- * @apiUse NO_PERMISSION
+ * @apiParam {Number} page The page number.
*
- * @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data Array of new tickets.
+ * @apiUse NO_PERMISSION
+ * @apiUse INVALID_PAGE
+ *
+ * @apiSuccess {Object} data Information about a tickets and quantity of pages.
+ * @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data.tickets Array of new tickets of the current page.
+ * @apiSuccess {Number} data.page Number of current page.
+ * @apiSuccess {Number} data.pages Quantity of pages.
*
*/
@@ -27,7 +33,12 @@ class GetNewTicketsStaffController extends Controller {
public function validations() {
return[
'permission' => 'staff_1',
- 'requestData' => []
+ 'requestData' => [
+ 'page' => [
+ 'validation' => DataValidator::numeric(),
+ 'error' => ERRORS::INVALID_PAGE
+ ]
+ ]
];
}
public function handler() {
@@ -37,6 +48,8 @@ class GetNewTicketsStaffController extends Controller {
}
$user = Controller::getLoggedUser();
+ $page = Controller::request('page');
+
$query = ' (';
foreach ($user->sharedDepartmentList as $department) {
$query .= 'department_id=' . $department->id . ' OR ';
@@ -45,13 +58,22 @@ class GetNewTicketsStaffController extends Controller {
$ownerExists = RedBean::exec('SHOW COLUMNS FROM ticket LIKE \'owner_id\'');
if($ownerExists != 0) {
- $query .= 'FALSE) AND owner_id IS NULL';
+ $query .= 'FALSE) AND closed = 0 AND owner_id IS NULL';
} else {
- $query .= 'FALSE)';
+ $query .= 'FALSE) AND closed = 0';
}
+ $countTotal = Ticket::count($query);
+
+ $query .= ' ORDER BY unread_staff DESC';
+ $query .= ' LIMIT 10 OFFSET ' . ($page-1)*10;
+
$ticketList = Ticket::find($query);
- Response::respondSuccess($ticketList->toArray());
+ Response::respondSuccess([
+ 'tickets' => $ticketList->toArray(true),
+ 'page' => $page,
+ 'pages' => ceil($countTotal / 10)
+ ]);
}
}
diff --git a/server/controllers/staff/get-tickets.php b/server/controllers/staff/get-tickets.php
index 1f768042..e5393ca9 100755
--- a/server/controllers/staff/get-tickets.php
+++ b/server/controllers/staff/get-tickets.php
@@ -13,9 +13,16 @@ use Respect\Validation\Validator as DataValidator;
*
* @apiPermission staff1
*
+ * @apiParam {Number} page The page number.
+ * @apiParam {bool} closed Include closed tickets in the response.
+ *
* @apiUse NO_PERMISSION
- *
- * @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data Array of tickets assigned to the staff
+ * @apiUse INVALID_PAGE
+ *
+ * @apiSuccess {Object} data Information about a tickets and quantity of pages.
+ * @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data.tickets Array of tickets assigned to the staff of the current page.
+ * @apiSuccess {Number} data.page Number of current page.
+ * @apiSuccess {Number} data.pages Quantity of pages.
*
*/
@@ -26,12 +33,33 @@ class GetTicketStaffController extends Controller {
public function validations() {
return [
'permission' => 'staff_1',
- 'requestData' => []
+ 'requestData' => [
+ 'page' => [
+ 'validation' => DataValidator::numeric(),
+ 'error' => ERRORS::INVALID_PAGE
+ ]
+ ]
];
}
public function handler() {
$user = Controller::getLoggedUser();
- Response::respondSuccess($user->sharedTicketList->toArray());
+ $closed = Controller::request('closed');
+ $page = Controller::request('page');
+ $offset = ($page-1)*10;
+
+ if ($closed) {
+ $tickets = $user->withCondition(' TRUE LIMIT 10 OFFSET ?', [$offset])->sharedTicketList->toArray(true);
+ $countTotal = $user->countShared('ticket');
+ } else {
+ $tickets = $user->withCondition(' closed = ? LIMIT 10 OFFSET ?', ['0', $offset])->sharedTicketList->toArray(true);
+ $countTotal = $user->withCondition(' closed = ?', ['0'])->countShared('ticket');
+ }
+
+ Response::respondSuccess([
+ 'tickets' => $tickets,
+ 'page' => $page,
+ 'pages' => ceil($countTotal / 10)
+ ]);
}
-}
\ No newline at end of file
+}
diff --git a/server/controllers/system.php b/server/controllers/system.php
index 458dd036..61a07de1 100755
--- a/server/controllers/system.php
+++ b/server/controllers/system.php
@@ -1,32 +1,4 @@
setGroupPath('/system');
@@ -41,7 +13,8 @@ $systemControllerGroup->addController(new AddDepartmentController);
$systemControllerGroup->addController(new EditDepartmentController);
$systemControllerGroup->addController(new DeleteDepartmentController);
$systemControllerGroup->addController(new GetLogsController);
-$systemControllerGroup->addController(new GetMailTemplatesController);
+$systemControllerGroup->addController(new GetMailTemplateListController);
+$systemControllerGroup->addController(new GetMailTemplateController);
$systemControllerGroup->addController(new EditMailTemplateController);
$systemControllerGroup->addController(new RecoverMailTemplateController);
$systemControllerGroup->addController(new DisableRegistrationController);
diff --git a/server/controllers/system/edit-mail-template.php b/server/controllers/system/edit-mail-template.php
index 711a85da..b452cccb 100755
--- a/server/controllers/system/edit-mail-template.php
+++ b/server/controllers/system/edit-mail-template.php
@@ -9,20 +9,24 @@ use Respect\Validation\Validator as DataValidator;
*
* @apiGroup System
*
- * @apiDescription This path edit a mail template.
+ * @apiDescription This path edits a mail template.
*
* @apiPermission staff3
*
- * @apiParam {String} templateType The new type of the template.
- * @apiParam {String} language The new language of the template.
+ * @apiParam {String} template The template to edit.
+ * @apiParam {String} language The language of the template to edit.
* @apiParam {String} subject The new subject of the template.
- * @apiParam {String} body The new content of the template.
+ * @apiParam {String} text1 The first paragraph template.
+ * @apiParam {String} text2 The second paragraph template.
+ * @apiParam {String} text3 The third paragraph template.
*
* @apiUse NO_PERMISSION
* @apiUse INVALID_TEMPLATE
* @apiUse INVALID_LANGUAGE
* @apiUse INVALID_SUBJECT
- * @apiUse INVALID_BODY
+ * @apiUse INVALID_TEXT_1
+ * @apiUse INVALID_TEXT_2
+ * @apiUse INVALID_TEXT_3
*
* @apiSuccess {Object} data Empty object
*
@@ -32,11 +36,16 @@ class EditMailTemplateController extends Controller {
const PATH = '/edit-mail-template';
const METHOD = 'POST';
+ private $langauge;
+ private $templateType;
+ private $subject;
+ private $texts;
+
public function validations() {
return [
'permission' => 'staff_3',
'requestData' => [
- 'templateType' => [
+ 'template' => [
'validation' => DataValidator::length(4),
'error' => ERRORS::INVALID_TEMPLATE
],
@@ -48,28 +57,87 @@ class EditMailTemplateController extends Controller {
'validation' => DataValidator::length(4),
'error' => ERRORS::INVALID_SUBJECT
],
- 'body' => [
- 'validation' => DataValidator::length(4),
- 'error' => ERRORS::INVALID_BODY
- ]
]
];
}
public function handler() {
- $language = Controller::request('language');
- $templateType = Controller::request('templateType');
- $subject = Controller::request('subject', true);
- $body = Controller::request('body');
+ $this->language = Controller::request('language');
+ $this->templateType = Controller::request('template');
+ $this->subject = Controller::request('subject', true);
+ $this->texts = [
+ Controller::request('text1'),
+ Controller::request('text2'),
+ Controller::request('text3'),
+ ];
+
+ $mailTemplate = MailTemplate::findOne(' language = ? AND template = ?', [$this->language, $this->templateType]);
- $mailTemplate = MailTemplate::findOne(' language = ? AND type = ?', [$language, $templateType]);
if($mailTemplate->isNull()) {
throw new Exception(ERRORS::INVALID_TEMPLATE);
}
- $mailTemplate->subject = $subject;
- $mailTemplate->body = $body;
+
+ $this->validateReplacements();
+
+ $mailTemplate->subject = $this->subject;
+ $mailTemplate->text1 = $this->texts[0];
+ $mailTemplate->text2 = $this->texts[1];
+ $mailTemplate->text3 = $this->texts[2];
+
$mailTemplate->store();
Response::respondSuccess();
}
+
+ public function validateReplacements() {
+ $originalText = MailTexts::getTexts()[$this->language][$this->templateType];
+
+ if(!$this->includes(
+ $this->getReplacementStrings($originalText[1]),
+ $this->getReplacementStrings($this->texts[0])
+ )) {
+ throw new Exception(ERRORS::INVALID_TEXT_1);
+ }
+
+ if(!$this->includes(
+ $this->getReplacementStrings($originalText[2]),
+ $this->getReplacementStrings($this->texts[1])
+ )) {
+ throw new Exception(ERRORS::INVALID_TEXT_2);
+ }
+
+ if(!$this->includes(
+ $this->getReplacementStrings($originalText[3]),
+ $this->getReplacementStrings($this->texts[2])
+ )) {
+ throw new Exception(ERRORS::INVALID_TEXT_3);
+ }
+ }
+
+ public function includes($array1, $array2) {
+ foreach($array1 as $item) {
+ if(!in_array($item, $array2)) return false;
+ }
+
+ return true;
+ }
+
+ public function getReplacementStrings($string) {
+ $replacements = [];
+
+ for($i=0; $ideleteLastLogs();
$page = Controller::request('page');
$logList = Log::find('ORDER BY id desc LIMIT ? OFFSET ?', [10, 10*($page-1)]);
Response::respondSuccess($logList->toArray());
}
-}
\ No newline at end of file
+
+ public function deleteLastLogs() {
+ $removeOlderThanDays = 31;
+ $oldDate = floor(Date::getPreviousDate($removeOlderThanDays) / 10000);
+
+ try {
+ RedBean::exec("DELETE FROM log WHERE date < $oldDate");
+ } catch(Exception $e) {}
+ }
+}
diff --git a/server/controllers/system/get-mail-templates.php b/server/controllers/system/get-mail-template-list.php
old mode 100755
new mode 100644
similarity index 58%
rename from server/controllers/system/get-mail-templates.php
rename to server/controllers/system/get-mail-template-list.php
index 8dfbffa5..3a7409a7
--- a/server/controllers/system/get-mail-templates.php
+++ b/server/controllers/system/get-mail-template-list.php
@@ -2,25 +2,25 @@
use Respect\Validation\Validator as DataValidator;
/**
- * @api {post} /system/get-mail-templates Get mail templates
+ * @api {post} /system/get-mail-template-list Get mail template
* @apiVersion 4.3.0
*
- * @apiName Get mail templates
+ * @apiName Get mail template list
*
* @apiGroup System
*
- * @apiDescription This path retrieves the all the mail templates.
+ * @apiDescription This path retrieves the list of mail templates
*
* @apiPermission staff3
*
* @apiUse NO_PERMISSION
- *
+ *
* @apiSuccess {[MailTemplate](#api-Data_Structures-ObjectMailtemplate)[]} data Array of mail templates
*
*/
-class GetMailTemplatesController extends Controller {
- const PATH = '/get-mail-templates';
+class GetMailTemplateListController extends Controller {
+ const PATH = '/get-mail-template-list';
const METHOD = 'POST';
public function validations() {
@@ -31,7 +31,6 @@ class GetMailTemplatesController extends Controller {
}
public function handler() {
- Response::respondSuccess(MailTemplate::getAll()->toArray());
-
+ Response::respondSuccess(array_keys(MailTemplate::getFilePaths()));
}
-}
\ No newline at end of file
+}
diff --git a/server/controllers/system/get-mail-template.php b/server/controllers/system/get-mail-template.php
new file mode 100755
index 00000000..86b63e6a
--- /dev/null
+++ b/server/controllers/system/get-mail-template.php
@@ -0,0 +1,57 @@
+ 'staff_3',
+ 'requestData' => [
+ 'template' => [
+ 'validation' => DataValidator::length(4),
+ 'error' => ERRORS::INVALID_TEMPLATE
+ ],
+ 'language' => [
+ 'validation' => DataValidator::length(2, 2),
+ 'error' => ERRORS::INVALID_LANGUAGE
+ ],
+ ]
+ ];
+ }
+
+ public function handler() {
+ $type = Controller::request('template');
+ $language = Controller::request('language');
+
+ $mailTemplate = MailTemplate::findOne(' language = ? AND template = ?', [$language, $type]);
+
+ if($mailTemplate->isNull()) {
+ throw new Exception(ERRORS::INVALID_TEMPLATE);
+ }
+
+ Response::respondSuccess($mailTemplate->toArray());
+ }
+}
diff --git a/server/controllers/system/get-settings.php b/server/controllers/system/get-settings.php
index 5dcd636b..3dcf7ca8 100755
--- a/server/controllers/system/get-settings.php
+++ b/server/controllers/system/get-settings.php
@@ -53,7 +53,8 @@ class GetSettingsController extends Controller {
'departments' => Department::getDepartmentNames(),
'supportedLanguages' => Language::getSupportedLanguages(),
'allowedLanguages' => Language::getAllowedLanguages(),
- 'session-prefix' => Setting::getSetting('session-prefix')
+ 'session-prefix' => Setting::getSetting('session-prefix')->getValue(),
+ 'mail-template-header-image' => Setting::getSetting('mail-template-header-image')->getValue()
];
} else {
$settingsList = [
@@ -70,7 +71,7 @@ class GetSettingsController extends Controller {
'supportedLanguages' => Language::getSupportedLanguages(),
'allowedLanguages' => Language::getAllowedLanguages(),
'user-system-enabled' => intval(Setting::getSetting('user-system-enabled')->getValue()),
- 'session-prefix' => Setting::getSetting('session-prefix')
+ 'session-prefix' => Setting::getSetting('session-prefix')->getValue()
];
}
}
diff --git a/server/controllers/system/init-database.php b/server/controllers/system/init-database.php
index 67aefd8c..3d5a8793 100755
--- a/server/controllers/system/init-database.php
+++ b/server/controllers/system/init-database.php
@@ -1,5 +1,4 @@
date('YmdHi', strtotime(' -12 day ')),
'ticket-gap' => Hashing::generateRandomPrime(100000, 999999),
'ticket-first-number' => Hashing::generateRandomNumber(100000, 999999),
- 'file-gap' => Hashing::generateRandomPrime(100000, 999999),
- 'file-first-number' => Hashing::generateRandomNumber(100000, 999999),
- 'file-quantity' => 0,
- 'session-prefix' => 'opensupports-'.Hashing::generateRandomToken().'_'
+ 'session-prefix' => 'opensupports-'.Hashing::generateRandomToken().'_',
+ 'mail-template-header-image' => 'http://opensupports.com/logo.png'
]);
}
private function storeMailTemplates() {
- $mails = InitialMails::retrieve();
+ $mailLanguages = MailTexts::getTexts();
- foreach ($mails as $mailType => $mailLanguages) {
- foreach ($mailLanguages as $mailLanguage => $mailContent) {
+ foreach ($mailLanguages as $language => $mailTemplate) {
+ foreach ($mailTemplate as $template => $texts) {
$mailTemplate = new MailTemplate();
$mailTemplate->setProperties([
- 'type' => $mailType,
- 'language' => $mailLanguage,
- 'subject' => $mailContent['subject'],
- 'body' => $mailContent['body']
+ 'template' => $template,
+ 'language' => $language,
+ 'subject' => $texts[0],
+ 'text1' => array_key_exists(1, $texts) ? $texts[1] : '',
+ 'text2' => array_key_exists(2, $texts) ? $texts[2] : '',
+ 'text3' => array_key_exists(3, $texts) ? $texts[3] : '',
]);
$mailTemplate->store();
diff --git a/server/controllers/system/recover-mail-template.php b/server/controllers/system/recover-mail-template.php
index 73803a37..8768d7e9 100755
--- a/server/controllers/system/recover-mail-template.php
+++ b/server/controllers/system/recover-mail-template.php
@@ -13,7 +13,7 @@ use Respect\Validation\Validator as DataValidator;
*
* @apiPermission staff3
*
- * @apiParam {String} templateType Type of the template.
+ * @apiParam {String} template Type of the template.
* @apiParam {String} language Lenguage of the template.
*
* @apiUse NO_PERMISSION
@@ -32,7 +32,7 @@ class RecoverMailTemplateController extends Controller {
return [
'permission' => 'staff_3',
'requestData' => [
- 'templateType' => [
+ 'template' => [
'validation' => DataValidator::length(4),
'error' => ERRORS::INVALID_TEMPLATE
],
@@ -45,23 +45,24 @@ class RecoverMailTemplateController extends Controller {
}
public function handler() {
- $type = Controller::request('templateType');
+ $templateType = Controller::request('template');
$language = Controller::request('language');
- $mailTemplate = MailTemplate::findOne(' language = ? AND type = ?', [$language, $type]);
+ $mailTemplate = MailTemplate::findOne(' language = ? AND template = ?', [$language, $templateType]);
if($mailTemplate->isNull()) {
- Response::respondError(ERRORS::INVALID_TEMPLATE);
- return;
+ throw new Exception(ERRORS::INVALID_TEMPLATE);
}
- $defaultTemplates = InitialMails::retrieve();
- $mailTemplate->body = $defaultTemplates[$type][$language]['body'] ;
- $mailTemplate->subject = $defaultTemplates[$type][$language]['subject'] ;
+ $mailTexts = MailTexts::getTexts()[$language][$templateType];
+
+ $mailTemplate->subject = $mailTexts[0];
+ $mailTemplate->text1 = (array_key_exists(1, $mailTexts)) ? $mailTexts[1] : '';
+ $mailTemplate->text2 = (array_key_exists(2, $mailTexts)) ? $mailTexts[2] : '';
+ $mailTemplate->text3 = (array_key_exists(3, $mailTexts)) ? $mailTexts[3] : '';
$mailTemplate->store();
-
- Response::respondSuccess();
+ Response::respondSuccess();
}
-}
\ No newline at end of file
+}
diff --git a/server/controllers/ticket.php b/server/controllers/ticket.php
index 2cce64c5..3648e604 100755
--- a/server/controllers/ticket.php
+++ b/server/controllers/ticket.php
@@ -1,19 +1,4 @@
setGroupPath('/ticket');
diff --git a/server/controllers/user.php b/server/controllers/user.php
index 7d10b549..d65541f7 100755
--- a/server/controllers/user.php
+++ b/server/controllers/user.php
@@ -1,23 +1,4 @@
setGroupPath('/user');
diff --git a/server/controllers/user/get.php b/server/controllers/user/get.php
index f871a870..a7f8126f 100755
--- a/server/controllers/user/get.php
+++ b/server/controllers/user/get.php
@@ -18,7 +18,7 @@ DataValidator::with('CustomValidations', true);
* @apiUse INVALID_CREDENTIALS
*
* @apiSuccess {Object} data Information about an user
- * @apiSuccess {String} data.name Name of the user
+ * @apiSuccess {String} data.name Name of the user
* @apiSuccess {String} data.email Email of the user
* @apiSuccess {Boolean} data.verified Indicates if the user is verified
* @apiSuccess {Object} data Information about an user
@@ -48,7 +48,7 @@ class GetUserController extends Controller {
$ticketList = $user->sharedTicketList;
foreach($ticketList as $ticket) {
- $parsedTicketList[] = $ticket->toArray();
+ $parsedTicketList[] = $ticket->toArray(true);
}
Response::respondSuccess([
@@ -58,4 +58,4 @@ class GetUserController extends Controller {
'tickets' => $parsedTicketList
]);
}
-}
\ No newline at end of file
+}
diff --git a/server/controllers/user/login.php b/server/controllers/user/login.php
index 28b5c45d..6b289775 100755
--- a/server/controllers/user/login.php
+++ b/server/controllers/user/login.php
@@ -1,4 +1,5 @@
clearOldRememberTokens();
+
if ($this->checkInputCredentials() || $this->checkRememberToken()) {
if($this->userInstance->verificationToken !== null) {
throw new Exception(ERRORS::UNVERIFIED_USER);
@@ -66,7 +70,7 @@ class LoginController extends Controller {
}
$this->createUserSession();
- $this->createSessionCookie();
+ $this->createRememberToken();
if(Controller::request('staff')) {
$this->userInstance->lastLogin = Date::getCurrentDate();
$this->userInstance->store();
@@ -106,7 +110,8 @@ class LoginController extends Controller {
'userEmail' => $userInstance->email,
'staff' => Controller::request('staff'),
'token' => Session::getInstance()->getToken(),
- 'rememberToken' => $this->rememberToken
+ 'rememberToken' => $this->rememberToken,
+ 'rememberExpiration' => $this->rememberExpiration
);
}
@@ -138,18 +143,30 @@ class LoginController extends Controller {
return $userInstance;
}
- private function createSessionCookie() {
- $remember = Controller::request('remember');
+ private function clearOldRememberTokens() {
+ $currentDate = Date::getCurrentDate();
+
+ try {
+ RedBean::exec("DELETE FROM sessioncookie WHERE expiration_date < $currentDate");
+ } catch(Exception $e) {}
+ }
+
+ private function createRememberToken() {
+ $remember = Controller::request('remember');
+
if ($remember) {
$this->rememberToken = Hashing::generateRandomToken();
+ $this->rememberExpiration = Date::getNextDate(30);
$sessionCookie = new SessionCookie();
$sessionCookie->setProperties(array(
'user' => $this->userInstance,
'token' => $this->rememberToken,
'ip' => $_SERVER['REMOTE_ADDR'],
- 'creationDate' => date('d-m-Y (H:i:s)')
+ 'creationDate' => Date::getCurrentDate(),
+ 'expirationDate' => $this->rememberExpiration
));
+
$sessionCookie->store();
}
}
diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php
index 5776d831..add61421 100755
--- a/server/data/ERRORS.php
+++ b/server/data/ERRORS.php
@@ -187,6 +187,18 @@
* @apiDefine USER_DISABLED
* @apiError {String} USER_DISABLED User is disabled
*/
+/**
+ * @apiDefine INVALID_TEXT_1
+ * @apiError {String} INVALID_TEXT_1 text1 of mail template has an invalid syntax or missing variables
+ */
+/**
+ * @apiDefine INVALID_TEXT_2
+ * @apiError {String} INVALID_TEXT_2 text2 of mail template has an invalid syntax or missing variables
+ */
+/**
+ * @apiDefine INVALID_TEXT_3
+ * @apiError {String} INVALID_TEXT_3 text3 of mail template has an invalid syntax or missing variables
+ */
class ERRORS {
const INVALID_CREDENTIALS = 'INVALID_CREDENTIALS';
@@ -237,4 +249,7 @@ class ERRORS {
const ALREADY_DISABLED = 'ALREADY_DISABLED';
const ALREADY_ENABLED = 'ALREADY_ENABLED';
const USER_DISABLED = 'USER_DISABLED';
+ const INVALID_TEXT_1 = 'INVALID_TEXT_1';
+ const INVALID_TEXT_2 = 'INVALID_TEXT_2';
+ const INVALID_TEXT_3 = 'INVALID_TEXT_3';
}
diff --git a/server/data/InitialMails.php b/server/data/InitialMails.php
deleted file mode 100755
index 70030839..00000000
--- a/server/data/InitialMails.php
+++ /dev/null
@@ -1,57 +0,0 @@
- 'data/mail-templates/user-signup.html',
- 'USER_PASSWORD' => 'data/mail-templates/user-edit-password.html',
- 'USER_EMAIL' => 'data/mail-templates/user-edit-email.html',
- 'PASSWORD_FORGOT' => 'data/mail-templates/user-password-forgot.html',
- 'USER_SYSTEM_DISABLED' => 'data/mail-templates/user-system-disabled.html',
- 'USER_SYSTEM_ENABLED' => 'data/mail-templates/user-system-enabled.html',
- 'TICKET_CREATED' => 'data/mail-templates/ticket-created.html',
- 'TICKET_RESPONDED' => 'data/mail-templates/ticket-responded.html',
- 'TICKET_CLOSED' => 'data/mail-templates/ticket-closed.html',
- 'TICKET_CREATED_STAFF' => 'data/mail-templates/ticket-created-staff.html',
- ];
- array_shift($texts);
-
- $matches = [];
- foreach($texts as $key => $val) {
- $matches[] = '{{' . $templateCode . '_MATCH_' . ($key + 1) . '}}';
- }
-
- return str_replace($matches, $texts, file_get_contents($templateFilePaths[$templateCode]));
- }
-
- public static function generateTemplateTexts($templateCode) {
- $mailTexts = MailTexts::getTexts();
- $templateTexts = [];
-
- foreach($mailTexts as $language => $languageTexts) {
- $templateTexts[$language] = [
- 'subject' => $languageTexts[$templateCode][0],
- 'body' => InitialMails::getBody($templateCode, $languageTexts[$templateCode]),
- ];
- }
-
- return $templateTexts;
- }
-
- public static function retrieve() {
- return [
- 'USER_SIGNUP' => InitialMails::generateTemplateTexts('USER_SIGNUP'),
- 'USER_PASSWORD' => InitialMails::generateTemplateTexts('USER_PASSWORD'),
- 'USER_EMAIL' => InitialMails::generateTemplateTexts('USER_EMAIL'),
- 'PASSWORD_FORGOT' => InitialMails::generateTemplateTexts('PASSWORD_FORGOT'),
- 'USER_SYSTEM_DISABLED' => InitialMails::generateTemplateTexts('USER_SYSTEM_DISABLED'),
- 'USER_SYSTEM_ENABLED' => InitialMails::generateTemplateTexts('USER_SYSTEM_ENABLED'),
- 'TICKET_CREATED' => InitialMails::generateTemplateTexts('TICKET_CREATED'),
- 'TICKET_RESPONDED' => InitialMails::generateTemplateTexts('TICKET_RESPONDED'),
- 'TICKET_CLOSED' => InitialMails::generateTemplateTexts('TICKET_CLOSED'),
- 'TICKET_CREATED_STAFF' => InitialMails::generateTemplateTexts('TICKET_CREATED_STAFF'),
- ];
- }
-}
diff --git a/server/data/MailTexts.php b/server/data/MailTexts.php
index 6721e058..3c291d31 100644
--- a/server/data/MailTexts.php
+++ b/server/data/MailTexts.php
@@ -8,7 +8,6 @@ class MailTexts {
'Verify your account',
'Welcome to our support center, {{name}}!. We need you to verify this email in order to get access to your account.',
'Use this code in {{url}}/verify-token/{{to}}/{{verificationToken}} or click the button below.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Password edited - OpenSupports',
@@ -25,28 +24,24 @@ class MailTexts {
'Recover password',
'Hi, {{name}}. You have requested to recover your password.',
'Use this code in {{url}}/recover-password?email={{to}}&token={{token}} or click the button below.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Access system changed - OpenSupports',
'Access system changed',
'Hello, {{name}}. The system to access tickets has changed.',
'You can access and see to your tickets by using your email and the ticket number.Click in the button below to see your tickets.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Account created - OpenSupports',
'Account created',
'Hello, {{name}}. We have created an account where you can access the tickets you have sent us.',
'You can access your account by using this email ({{to}}) and password below.Please change the password as soon as you log in.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Ticket created - OpenSupports',
'Ticket created',
'Hello, {{name}}. You have sent a new ticket titled {{title}} to our support center.',
'You can access to the ticket by its ticket number or you can click on the button below.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} New response - OpenSupports',
@@ -65,7 +60,6 @@ class MailTexts {
'Ticket created',
'User {{name}} has created a new ticket titled {{title}}.',
'You can access to the ticket by its ticket number.',
- '{{ticketNumber}}'
],
],
'cn' => [
@@ -74,7 +68,6 @@ class MailTexts {
'验证您的帐户',
'欢迎来到我们的支援中心{{name}} !. 我们需要您验证此电子邮件才能访问您的帐户。',
'使用此代码 {{url}}/verify-token/{{to}}/{{verificationToken}} 或单击下面的按钮.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'密码已编辑 - OpenSupports',
@@ -91,28 +84,24 @@ class MailTexts {
'恢复密码',
'喂 {{name}}。 您已要求恢复密码。',
'使用此代码 {{url}}/recover-password?email={{to}}&token={{token}} 或单击下面的按钮.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'访问系统更改 - OpenSupports',
'访问系统更改',
'您好,{{name}}。 访问票证的系统已更改。',
'您可以通过使用您的电子邮件和票号访问和查看您的机票。 点击下面的按钮查看您的票。',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'帐户已创建 - OpenSupports',
'帐户已创建',
'您好,{{name}}。 我们已经创建了一个帐户,您可以访问您发送给我们的票。',
'您可以在下面使用此电子邮件 ({{to}}) 和密码访问您的帐户。 请在登录后立即更改密码。',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} 已创建票证 - OpenSupports',
'票据创建',
'您好,{{name}}。 您已将一张名为 {{title}} 的新票发送到我们的支持中心。',
'您可以通过其票号访问票证。 或者你可以点击下面的按钮。',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} 新反应 - OpenSupports',
@@ -131,7 +120,6 @@ class MailTexts {
'票据创建',
'用戶 {{name}}。 他創造了一個題為新票 {{title}}。',
'您可以通过其票号访问票证。',
- '{{ticketNumber}}'
],
],
'de' => [
@@ -140,7 +128,6 @@ class MailTexts {
'Überprüfen Sie Ihr Konto',
'Willkommen in unserem Support-Center, {{name}} !. Wir müssen Sie diese E-Mail bestätigen, um Zugang zu Ihrem Konto zu erhalten.',
'Verwenden Sie diesen Code in {{url}}/verify-token/{{to}}/{{verificationToken}} oder klicken Sie auf die Schaltfläche unten.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Passwort bearbeitet - OpenSupports',
@@ -157,28 +144,24 @@ class MailTexts {
'Passwort wiederherstellen',
'Hallo, {{name}}. Sie haben aufgefordert, Ihr Passwort wiederherzustellen.',
'Verwenden Sie diesen Code in {{url}}/recover-password?email={{to}}&token={{token}} oder klicken Sie auf die Schaltfläche unten.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Access system changed - OpenSupports',
'Zugriffssystem geändert',
'Hallo, {{name}}. Das System für den Zugriff auf Tickets hat sich geändert.',
'können mit Ihren E-Mails und der Ticketnummer auf Ihre Tickets zugreifen und sie sehen.Klicken Sie auf die Schaltfläche unten, um Ihre Tickets zu sehen.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Account erstellt - OpenSupports',
'Account erstellt',
'Hallo, {{name}}. Wir haben ein Konto erstellt, wo Sie auf die Tickets zugreifen können, die Sie uns geschickt haben.',
'Sie können auf Ihr Konto zugreifen, indem Sie diese E-Mail ({{to}}) und das Passwort unten verwenden.Bitte ändern Sie das Passwort, sobald Sie sich anmelden.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Ticket erstellt - OpenSupports',
'Ticket erstellt',
'Hallo, {{name}}. Sie haben ein neues Ticket mit dem Titel {{title}} an unser Support-Center geschickt.',
'Sie können das Ticket nach der Fahrkartennummer erreichen. Oder klicken Sie auf die Schaltfläche unten.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Neue Antwort - OpenSupports',
@@ -197,7 +180,6 @@ class MailTexts {
'Ticket erstellt',
'Der Benutzer {{name}} hat ein neues Ticket erstellt berechtigt {{title}}.',
'Sie können das Ticket nach der Fahrkartennummer erreichen.',
- '{{ticketNumber}}'
],
],
'es' => [
@@ -206,7 +188,6 @@ class MailTexts {
'Verifica tu cuenta',
'Bienvenido a nuestro contro de soporte, {{name}}!. Necesitamos que verifiques este email para poder acceder a tu cuenta.',
'Usá este código en {{url}}/verify-token/{{to}}/{{verificationToken}} o hacé click en el botón de abajo.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Contraseña a cambiado - OpenSupports',
@@ -223,28 +204,24 @@ class MailTexts {
'Recuperar contraseña',
'Hola, {{name}}. Has requerido recuperar tu contraseña.',
'Usá este codigo en {{url}}/recover-password?email={{to}}&token={{token}} o hacé click en el botón de abajo.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Sistema de acceso cambiado - OpenSupports',
'Sistema de acceso cambiado',
'Hola, {{name}}. El sistema para acceder a los tickets ha cambiado.',
'Ahora podes acceder a los tickets usando tu email y el numero de ticket.Hacé click en el botón de abajo para poder ver los tickets.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Cuenta creada - OpenSupports',
'Cuenta creada',
'Hola, {{name}}. Hemos creado una cuenta donde puedes acceder a los tickets que nos has enviado.',
'Puedes acceder usando tu email ({{to}}) y el la contraseña de abajo.Por favor, cambia tu contraseña tan pronto como ingreses al panel de usuario.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Ticket creado - OpenSupports',
'Ticket creado',
'Hola, {{name}}. Has creado un nuevo ticket titulado {{title}} en nuestro sistema de soporte.',
'Puedes ver el ticket usando el numero de ticket prensentado abajo o puedes hacer click en el botón de más abajo.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Nueva respuesta - OpenSupports',
@@ -263,7 +240,6 @@ class MailTexts {
'Ticket creado',
'El usuario {{name}} ha creado un nuevo ticket titulado {{title}}.',
'Puedes ver el ticket usando el numero de ticket prensentado abajo.',
- '{{ticketNumber}}'
],
],
'fr' => [
@@ -272,7 +248,6 @@ class MailTexts {
'Vérifiez votre compte',
'Bienvenue dans notre centre de support, {{name}}!. Nous vous demandons de vérifier cet e-mail afin d accéder à votre compte.',
'Utilisez ce code dans {{url}}/verify-token/{{to}}/{{verificationToken}} ou cliquez sur le bouton ci-dessous.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Mot de passe modifié - OpenSupports',
@@ -289,28 +264,24 @@ class MailTexts {
'Récupérer mot de passe',
'Salut, {{name}}. Vous avez demandé à récupérer votre mot de passe.',
'Utilisez ce code dans {{url}}/recover-password?email={{to}}&token={{token}} ou cliquez sur le bouton ci-dessous.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Système d\'accès modifié - OpenSupports',
'Système d\'accès modifié',
'Bonjour, {{name}}.Le système d\'accès aux tickets a changé.',
'Vous pouvez accéder et voir vos billets en utilisant votre email et le numéro de ticket.Cliquez sur le bouton ci-dessous pour voir vos billets.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Compte créé - OpenSupports',
'Compte créé',
'Bonjour, {{name}}. Nous avons créé un compte où vous pouvez accéder aux billets que vous nous avez envoyés.',
'Vous pouvez accéder à votre compte en utilisant ce courriel ({{to}}) et votre mot de passe ci-dessous.Veuillez modifier le mot de passe dès que vous vous connectez.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Ticket créé - OpenSupports',
'Ticket créé',
'Bonjour, {{name}}. Vous avez envoyé un nouveau ticket intitulé {{title}} à notre centre de support.',
'Vous pouvez accéder au billet par son numéro de ticket. Ou vous pouvez cliquer sur le bouton ci-dessous.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Nouvelle réponse - OpenSupports',
@@ -329,7 +300,6 @@ class MailTexts {
'Ticket créé',
'L\'utilisateur {{name}}. a créé un nouveau poste intitulé {{title}}.',
'Vous pouvez accéder au billet par son numéro de ticket.',
- '{{ticketNumber}}'
],
],
'in' => [
@@ -338,7 +308,6 @@ class MailTexts {
'अपने खाते को सत्यापित करें',
'हमारे समर्थन केंद्र में आपका स्वागत है {{name}}!. आपके खाते तक पहुंच प्राप्त करने के लिए हमें आपको यह ईमेल सत्यापित करने की आवश्यकता है।',
'इस कोड का उपयोग करें {{url}}/verify-token/{{to}}/{{verificationToken}} या नीचे दिए गए बटन पर क्लिक करें।',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'sandi diedit - OpenSupports',
@@ -355,28 +324,24 @@ class MailTexts {
'गोपनीय शब्द पुन प्राप्त करे',
'नमस्ते {{name}}. आपने अपना पासवर्ड पुनर्प्राप्त करने का अनुरोध किया है',
'इस कोड का उपयोग करें {{url}}/recover-password?email={{to}}&token={{token}} या नीचे दिए गए बटन पर क्लिक करें.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'sistem akses berubah - OpenSupports',
'एक्सेस सिस्टम बदल गया',
'नमस्ते {{name}}. टिकट का उपयोग करने के लिए सिस्टम बदल गया है।',
'आप अपने ईमेल और टिकट नंबर का उपयोग करके अपने टिकट तक पहुंच सकते हैं और देख सकते हैं।अपने टिकट देखने के लिए नीचे दिए गए बटन पर क्लिक करें।',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Akun telah dibuat - OpenSupports',
'खाता बन गय',
'नमस्ते {{name}}. हमने एक खाता बनाया है, जहां आप हमारे द्वारा भेजे गए टिकटों तक पहुंच सकते हैं।',
'आप इस ईमेल ({{to}}) और नीचे दिए गए पासवर्ड का उपयोग करके अपने खाते का उपयोग कर सकते हैं।जैसे ही आप लॉग इन करते हैं, तभी पासवर्ड बदल दें।',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} tiket dibuat - OpenSupports',
'टिकट बनाय',
'नमस्ते {{name}}. आपने हमारे समर्थन केंद्र पर {{title}} नामक एक नया टिकट भेजा है.',
'आप अपने टिकट नंबर से टिकट तक पहुंच सकते हैं। या आप नीचे दिए गए बटन पर क्लिक कर सकते हैं।',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} tanggapan baru - OpenSupports',
@@ -395,7 +360,6 @@ class MailTexts {
'टिकट बनाया',
'उपयोगकर्ता {{name}} हकदार एक नया पद बनाया गया है {{title}}.',
'आप अपने टिकट नंबर से टिकट तक पहुंच सकते हैं।',
- '{{ticketNumber}}'
],
],
'it' => [
@@ -404,7 +368,6 @@ class MailTexts {
'Verifica il tuo account',
'Benvenuto, {{name}}!. Devi verificare questa email per accedere al tuo account.',
'Clicca sul link {{url}}/verify-token/{{to}}/{{verificationToken}} o clicca sul pulsante qui sotto.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Password modificata - OpenSupports',
@@ -421,28 +384,24 @@ class MailTexts {
'Recupera password',
'Ciao, {{name}}. Hai richiesto di recuperare la tua password.',
'Clicca sul link {{url}}/recover-password?email={{to}}&token={{token}} o clicca sul pulsante qui sotto.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Il sistema di accesso è cambiato - OpenSupports',
'Modifica sistema di accesso',
'Ciao, {{name}}. Il sistema di accesso ai tuoi tickets è cambiato.',
'Puoi accedere ai tuoi ticket usando la tua email e il numero del ticket.Clicca sul bottone qui sotto per vedere i tuoi tickets.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Account creato - OpenSupports',
'Account creato',
'Ciao, {{name}}. Abbiamo creato il tuo account.',
' Puoi accedere al tuo account utilizzando questa email ({{to}}) e la password qui sotto.Ti consigliamo di cambiare la password dopo il primo accesso.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} ticket creato - OpenSupports',
'Ticket inviato',
'Ciao, {{name}}. Hai inviato un nuovo ticket {{title}} al nostro centro si assistenza.',
'È possibile accedere al ticket attraverso il numero del ticket. Oppure puoi cliccare sul bottone qui sotto.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Ticket risposto - OpenSupports',
@@ -461,7 +420,6 @@ class MailTexts {
'Ticket inviato',
'l\'utente {{name}} ha creato un nuovo titolo dal titolo {{title}}',
'È possibile accedere al ticket con il suo numero di ticket.',
- '{{ticketNumber}}'
],
],
'jp' => [
@@ -470,7 +428,6 @@ class MailTexts {
'アカウントを確認する',
'サポートセンターへようこそ, {{name}}!. アカウントにアクセスするには、このメールを確認する必要があります。',
'でこのコードを使用 {{url}}/verify-token/{{to}}/{{verificationToken}} 下のボタンをクリックしてください.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'パスワードの編集 - OpenSupports',
@@ -487,28 +444,24 @@ class MailTexts {
'パスワードを回復',
'こんにちは、{{name}}。 パスワードの回復を要求しました。',
'でこのコードを使用 {{url}}/recover-password?email={{to}}&token={{token}} 下のボタンをクリックしてください.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'アクセスシステムが変更されました - OpenSupports',
'アクセスシステムが変更されました',
'こんにちは、{{name}}。 チケットにアクセスするシステムが変更されました。',
'あなたはあなたの電子メールとチケット番号を使ってチケットにアクセスして見ることができます。チケットを見るには、下のボタンをクリックしてください。',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'アカウントが作成されました - OpenSupports',
'アカウントが作成されました',
'こんにちは、{{name}}。 あなたが送ったチケットにアクセスできるアカウントを作成しました。',
'下記のメール({{to}})とパスワードを使用してアカウントにアクセスできます。ログインするとすぐにパスワードを変更してください。',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} チケットが作成されました - OpenSupports',
'チケットが作成されました',
'こんにちは、{{name}}。{{title}} という新しいチケットをサポートセンターにお送りしました。',
'そのチケット番号でチケットにアクセスできます。 または、下のボタンをクリックしてください。',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} 新しい応答 - OpenSupports',
@@ -527,7 +480,6 @@ class MailTexts {
'チケットが作成されました',
'ユーザーは {{name}} 彼は題した新しいチケットを作成しました {{title}}。',
'そのチケット番号でチケットにアクセスできます。',
- '{{ticketNumber}}'
],
],
'pt' => [
@@ -536,7 +488,6 @@ class MailTexts {
'Verifique sua conta',
'Bem-vindo ao nosso centro de suporte, {{name}}!. Precisamos que você verifique este e-mail para acessar sua conta.',
'Use este código em {{url}}/verify-token/{{to}}/{{verificationToken}} ou clique no botão abaixo.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Senha editada - OpenSupports',
@@ -553,28 +504,24 @@ class MailTexts {
'Recuperar senha',
'Olá, {{name}}. Você solicitou a recuperação da sua senha.',
'Use este código em {{url}}/recover-password?email={{to}}&token={{token}} ou clique no botão abaixo.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Sistema de acesso alterado - OpenSupports',
'Sistema de acesso alterado',
'Oi, {{name}}. O sistema de acesso aos tickets mudou.',
'Você pode acessar e ver seus bilhetes usando seu e-mail eo número do bilhete.Clique no botão abaixo para ver os seus bilhetes.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Conta criada - OpenSupports',
'Conta criada',
'Oi, {{name}}. Criamos uma conta onde você pode acessar os ingressos que você nos enviou.',
'Você pode acessar sua conta usando este e-mail ({{to}}) e a senha abaixo.Por favor, altere a senha assim que fizer login.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Ticket criado - OpenSupports',
'Ticket criado',
'Olá, {{name}}. Você enviou um novo ticket intitulado {{title}} para o nosso centro de suporte.',
'Você pode acessar o bilhete pelo seu número de bilhete. Ou você pode clicar no botão abaixo.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Nova resposta - OpenSupports',
@@ -593,7 +540,6 @@ class MailTexts {
'Ticket criado',
'O usuário {{name}} criou um novo bilhete de direito {{title}}.',
'Você pode acessar o bilhete pelo seu número de bilhete.',
- '{{ticketNumber}}'
],
],
'ru' => [
@@ -602,7 +548,6 @@ class MailTexts {
'подтвердите ваш аккаунт',
'Добро пожаловать в наш центр поддержки, {{name}}!. Нам нужно, чтобы вы подтвердили это письмо, чтобы получить доступ к вашей учетной записи.',
'Используйте этот код в {{url}}/verify-token/{{to}}/{{verificationToken}} или нажмите кнопку ниже.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Пароль изменен - OpenSupports',
@@ -619,28 +564,24 @@ class MailTexts {
'Восстановить пароль',
'Здравствуй, {{name}}. Вы запросили восстановить пароль.',
'Используйте этот код в {{url}}/recover-password?email={{to}}&token={{token}} или нажмите кнопку ниже.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Система доступа изменена - OpenSupports',
'Система доступа изменена',
'Здравствуйте, {{name}}. Система доступа к билетам изменилась.',
'Вы можете получить доступ к своим билетам и посмотреть их, используя свою электронную почту и номер билета.Нажмите кнопку ниже, чтобы увидеть свои билеты.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Аккаунт создан - OpenSupports',
'Аккаунт создан',
'Здравствуйте, {{name}}. Мы создали учетную запись, где вы можете получить доступ к билетам, которые вы нам отправили.',
'Вы можете получить доступ к своей учетной записи, используя это электронное письмо ({{to}}) и пароль ниже.Измените пароль, как только вы войдете в систему.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Создан билет - OpenSupports',
'Создан билет',
'Здравствуйте, {{name}}. Вы отправили новый билет с названием {{title}} в наш центр поддержки.',
'Вы можете получить доступ к билету по его номеру билета. Или вы можете нажать на кнопку ниже.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Новый ответ - OpenSupports',
@@ -659,7 +600,6 @@ class MailTexts {
'Создан билет',
'Пользователь {{name}} создал новый билет под названием {{title}}.',
'Вы можете получить доступ к билету по его номеру билета.',
- '{{ticketNumber}}'
],
],
'tr' => [
@@ -668,7 +608,6 @@ class MailTexts {
'Hesabınızı doğrulayın',
'Destek merkezimize hoş geldiniz, {{name}}!. Hesabınıza erişebilmek için bu e-postayı doğrulamanız gerekiyor.',
'Bu kodu şu adreste kullanın {{url}}/verify-token/{{to}}/{{verificationToken}} veya aşağıdaki butona tıklayın.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Şifre düzenlendi - OpenSupports',
@@ -685,28 +624,24 @@ class MailTexts {
'Şifre kurtarma',
'Merhaba, {{name}}. Şifrenizi geri yüklemenizi istediniz.',
'Bu kodu şu adreste kullanın {{url}}/recover-password?email={{to}}&token={{token}} veya aşağıdaki butona tıklayın.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Erişim sistemi değiştirildi - OpenSupports',
'Erişim sistemi değiştirildi',
'Merhaba, {{name}}. Biletleri erişmek için sistem değişti.',
'E-posta adresinizi ve bilet numaranızı kullanarak biletinize erişebilir ve biletlerini görebilirsiniz.Biletlerini görmek için aşağıdaki butona tıklayın.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Hesap oluşturuldu - OpenSupports',
'Hesap oluşturuldu',
'Merhaba, {{name}}. Bize gönderdiğiniz bilete erişebileceğiniz bir hesap oluşturduk.',
'Hesabınıza, ({{to}}) e-posta adresini kullanarak ve aşağıdaki şifreyle erişebilirsiniz.Lütfen giriş yaptığınızda şifreyi değiştirin.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Bilet oluşturuldu - OpenSupports',
'Bilet oluşturuldu',
'Merhaba, {{name}}. Destek merkezimize {{title}} başlıklı yeni bir bilet gönderdiniz.',
'Bilete bilet numarasından erişebilirsiniz. Ya da aşağıdaki düğmeyi tıklayabilirsiniz.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Yeni yanıt - OpenSupports',
@@ -725,7 +660,6 @@ class MailTexts {
'Bilet oluşturuldu',
'Kullanıcı {{name}} başlıklı yeni bir bilet yarattı {{title}} .',
'Bilete bilet numarasından erişebilirsiniz.',
- '{{ticketNumber}}'
],
],
'br' => [
@@ -734,7 +668,6 @@ class MailTexts {
'Verifique sua conta',
'Bem-vindo ao nosso centro de suporte, {{name}}!. Precisamos que você verifique este e-mail para acessar sua conta.',
'Use este código em {{url}}/verify-token/{{to}}/{{verificationToken}} ou clique no botão abaixo.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Senha editada - OpenSupports',
@@ -751,28 +684,24 @@ class MailTexts {
'Recuperar senha',
'Olá, {{name}}. Você solicitou a recuperação da sua senha.',
'Use este código em {{url}}/recover-password?email={{to}}&token={{token}} ou clique no botão abaixo.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Sistema de acesso alterado - OpenSupports',
'Sistema de acesso alterado',
'Oi, {{name}}. O sistema de acesso aos tickets mudou.',
'Você pode acessar e ver seus bilhetes usando seu e-mail eo número do bilhete.Clique no botão abaixo para ver os seus bilhetes.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
'Conta criada - OpenSupports',
'Conta criada',
'Oi, {{name}}. Criamos uma conta onde você pode acessar os ingressos que você nos enviou.',
'Você pode acessar sua conta usando este e-mail ({{to}}) e a senha abaixo.Por favor, altere a senha assim que fizer login.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Ticket criado - OpenSupports',
'Ticket criado',
'Olá, {{name}}. Você enviou um novo ticket intitulado {{title}} para o nosso centro de suporte.',
'Você pode acessar o bilhete pelo seu número de bilhete. Ou você pode clicar no botão abaixo.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Nova resposta - OpenSupports',
@@ -791,7 +720,6 @@ class MailTexts {
'Ticket criado',
'O usuário {{name}} criou um novo bilhete de direito {{title}}.',
'Você pode acessar o bilhete pelo seu número de bilhete.',
- '{{ticketNumber}}'
],
],
'gr' => [
@@ -800,7 +728,6 @@ class MailTexts {
'Επιβεβαιώστε το λογαριασμό σας',
'Καλώς ήρθατε στο κέντρο υποστήριξης {{name}} !. Πρέπει να επαληθεύσετε αυτό το μήνυμα ηλεκτρονικού ταχυδρομείου για να αποκτήσετε πρόσβαση στο λογαριασμό σας.',
'Χρησιμοποιήστε αυτόν τον κωδικό στο {{url}}/verify-token/{{to}}/{{verificationToken}} ή κάντε κλικ στο παρακάτω κουμπί.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Ο κωδικός επεξεργασίας τροποποιήθηκε- OpenSupports',
@@ -817,29 +744,24 @@ class MailTexts {
'Ανάκτηση κωδικού πρόσβασης',
'Γεια σου, {{name}}. Ζητήσατε να ανακτήσετε τον κωδικό πρόσβασής σας.',
'Χρησιμοποιήστε αυτόν τον κωδικό στο {{url}} / recover-password? Email = {{to}} & token = {{token}} ή κάντε κλικ στο παρακάτω κουμπί.',
- '{{token}}'
],
'USER_SYSTEM_DISABLED' => [
'Το σύστημα πρόσβασης άλλαξε - OpenSupports',
'Το σύστημα πρόσβασης άλλαξε',
'«Γεια σας, {{name}}. Το σύστημα πρόσβασης στα εισιτήρια έχει αλλάξει. ',
'Μπορείτε να έχετε πρόσβαση και να δείτε τα εισιτήριά σας χρησιμοποιώντας το email σας και τον αριθμό του εισιτηρίου.Κάντε κλικ στο κουμπί παρακάτω για να δείτε τα εισιτήριά σας.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
-
'Δημιουργία λογαριασμού - OpenSupports',
'Λογαριασμός που δημιουργήθηκε',
'«Γεια σας, {{name}}. Δημιουργήσαμε ένα λογαριασμό στον οποίο μπορείτε να έχετε πρόσβαση στα εισιτήρια που μας έχετε στείλει. ',
'Μπορείτε να αποκτήσετε πρόσβαση στο λογαριασμό σας χρησιμοποιώντας αυτό το μήνυμα ηλεκτρονικού ταχυδρομείου ({{to}}) i> και τον κωδικό πρόσβασης παρακάτω.Παρακαλώ αλλάξτε τον κωδικό πρόσβασης μόλις συνδεθείτε.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Δημιουργήθηκε εισιτήριο - OpenSupports',
'Δημιουργήθηκε εισιτήριο',
'Χαίρετε, {{name}}.Έχετε στείλει ένα νέο εισιτήριο με τίτλο {{title}} i> στο κέντρο υποστήριξης.',
'Μπορείτε να έχετε πρόσβαση στο εισιτήριο με τον αριθμό εισιτηρίου του ή μπορείτε να κάνετε κλικ στο παρακάτω κουμπί.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Νέα απάντηση- OpenSupports',
@@ -858,7 +780,6 @@ class MailTexts {
'Incident aangemaakt',
'Gebruiker {{name}} heeft een nieuw incident aangemaakt met onderwerp {{title}}.',
'Bekijk dit incident via het incidentnummer.',
- '{{ticketNumber}}'
],
],
'nl' => [
@@ -867,7 +788,6 @@ class MailTexts {
'Verifieer uw account',
'Welkom bij het Support Center, {{name}}!. U moet uw account verifiëren om toegang te krijgen tot het systeem.',
'Use this code in {{url}}/verify-token/{{to}}/{{verificationToken}} or click the button below.',
- '{{verificationToken}}'
],
'USER_PASSWORD' => [
'Wachtwoord is aangepast - OpenSupports',
@@ -890,22 +810,18 @@ class MailTexts {
'Toegang tot incidenten is gewijzigd',
'Hallo, {{name}}. De toegang tot incidenten is gewijzigd.',
'U kunt uw incidenten bekijken d.m.v. uw email en het incident nummer.Klik op de knop hieronder om uw tickets te bekijken.',
- '{{tickets}}'
],
'USER_SYSTEM_ENABLED' => [
-
'Account is aangemaakt - OpenSupports',
'Account Aangemaakt',
'Hallo, {{name}}. We hebben een account voor u aangemaakt waarmee u uw incidenten kunt bekijken.',
'U kunt inloggen met dit email adres ({{to}}) en onderstaande wachtwoord.Verander alstublieft het wachtwoord na het inloggen.',
- '{{password}}'
],
'TICKET_CREATED' => [
'#{{ticketNumber}} Incident aangemaakt - OpenSupports',
'Incident aangemaakt',
'Hallo, {{name}}. U heeft zojuist een incident aangemaakt met onderwerp {{title}} in ons support center.',
'U kunt dit incident bekijken via het incidentnummer of via de knop hieronder.',
- '{{ticketNumber}}'
],
'TICKET_RESPONDED' => [
'#{{ticketNumber}} Nieuw antwoord - OpenSupports',
@@ -924,7 +840,6 @@ class MailTexts {
'Incident is gesloten',
'Hallo, {{name}}. Een incident met onderwerp {{title}} is gesloten.',
'U kunt dit incident bekijken via het incidentnummer. Of klik op de knop hieronder.',
- '{{ticketNumber}}'
],
],
];
diff --git a/server/data/mail-templates/ticket-closed.html b/server/data/mail-templates/ticket-closed.html
index bdecca82..6bfe8dac 100755
--- a/server/data/mail-templates/ticket-closed.html
+++ b/server/data/mail-templates/ticket-closed.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
diff --git a/server/data/mail-templates/ticket-created-staff.html b/server/data/mail-templates/ticket-created-staff.html
index b927e2bc..f6eb6a3d 100644
--- a/server/data/mail-templates/ticket-created-staff.html
+++ b/server/data/mail-templates/ticket-created-staff.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
@@ -345,7 +345,7 @@
- {{TICKET_CREATED_STAFF_MATCH_4}}
+ {{ticketNumber}}
|
diff --git a/server/data/mail-templates/ticket-created.html b/server/data/mail-templates/ticket-created.html
index 5a8334c5..360c8db2 100755
--- a/server/data/mail-templates/ticket-created.html
+++ b/server/data/mail-templates/ticket-created.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
@@ -345,7 +345,7 @@
- {{TICKET_CREATED_MATCH_4}}
+ {{ticketNumber}}
|
diff --git a/server/data/mail-templates/ticket-responded.html b/server/data/mail-templates/ticket-responded.html
index 3b3e014f..1507c06e 100755
--- a/server/data/mail-templates/ticket-responded.html
+++ b/server/data/mail-templates/ticket-responded.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
diff --git a/server/data/mail-templates/user-edit-email.html b/server/data/mail-templates/user-edit-email.html
index 5e275154..d50139c4 100755
--- a/server/data/mail-templates/user-edit-email.html
+++ b/server/data/mail-templates/user-edit-email.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
diff --git a/server/data/mail-templates/user-edit-password.html b/server/data/mail-templates/user-edit-password.html
index d96c5985..af8097c6 100755
--- a/server/data/mail-templates/user-edit-password.html
+++ b/server/data/mail-templates/user-edit-password.html
@@ -302,9 +302,9 @@
-
+ |
+
|
-
diff --git a/server/data/mail-templates/user-password-forgot.html b/server/data/mail-templates/user-password-forgot.html
index bf8ca548..eec0f4d1 100755
--- a/server/data/mail-templates/user-password-forgot.html
+++ b/server/data/mail-templates/user-password-forgot.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
@@ -345,7 +345,7 @@
- {{PASSWORD_FORGOT_MATCH_4}}
+ {{token}}
|
diff --git a/server/data/mail-templates/user-signup.html b/server/data/mail-templates/user-signup.html
index 6a976373..a85896cf 100755
--- a/server/data/mail-templates/user-signup.html
+++ b/server/data/mail-templates/user-signup.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
@@ -345,7 +345,7 @@
- {{USER_SIGNUP_MATCH_4}}
+ {{verificationToken}}
|
diff --git a/server/data/mail-templates/user-system-disabled.html b/server/data/mail-templates/user-system-disabled.html
index 9d860c10..9abf4350 100644
--- a/server/data/mail-templates/user-system-disabled.html
+++ b/server/data/mail-templates/user-system-disabled.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
@@ -345,7 +345,7 @@
- {{USER_SYSTEM_DISABLED_MATCH_4}}
+ {{tickets}}
|
diff --git a/server/data/mail-templates/user-system-enabled.html b/server/data/mail-templates/user-system-enabled.html
index 8a5b64a3..3789128d 100755
--- a/server/data/mail-templates/user-system-enabled.html
+++ b/server/data/mail-templates/user-system-enabled.html
@@ -302,8 +302,8 @@
-
-
+ |
+
|
@@ -345,7 +345,7 @@
- {{USER_SYSTEM_ENABLED_MATCH_4}}
+ {{password}}
|
diff --git a/server/index.php b/server/index.php
index 66048610..9f038796 100644
--- a/server/index.php
+++ b/server/index.php
@@ -15,49 +15,10 @@ if(defined('MYSQL_HOST') && defined('MYSQL_DATABASE') && defined('MYSQL_USER') &
\Slim\Slim::registerAutoLoader();
$app = new \Slim\Slim();
-// LOAD LIBRARIES
-include_once 'libs/Controller.php';
-include_once 'libs/ControllerGroup.php';
-include_once 'libs/Hashing.php';
-include_once 'libs/MailSender.php';
-include_once 'libs/Date.php';
-include_once 'libs/DataStoreList.php';
-include_once 'libs/LinearCongruentialGenerator.php';
-include_once 'libs/FileManager.php';
-include_once 'libs/FileDownloader.php';
-include_once 'libs/FileUploader.php';
-
-Controller::init();
-
-// LOAD DATA
-spl_autoload_register(function ($class) {
- $classPath = "data/{$class}.php";
-
- if(file_exists($classPath)) {
- include_once $classPath;
- }
-});
-
-// LOAD MODELS
-spl_autoload_register(function ($class) {
- $classPath = "models/{$class}.php";
-
- if(file_exists($classPath)) {
- include_once $classPath;
- }
-});
-
-// LOAD CUSTOM VALIDATIONS
-include_once 'libs/validations/dataStoreId.php';
-include_once 'libs/validations/userEmail.php';
-include_once 'libs/validations/staffEmail.php';
-include_once 'libs/validations/captcha.php';
-include_once 'libs/validations/validLanguage.php';
-include_once 'libs/validations/validTicketNumber.php';
-
// LOAD CONTROLLERS
foreach (glob('controllers/*.php') as $controller) {
include_once $controller;
}
+Controller::init();
$app->run();
diff --git a/server/libs/Controller.php b/server/libs/Controller.php
index 246e3e6f..85f8809a 100755
--- a/server/libs/Controller.php
+++ b/server/libs/Controller.php
@@ -1,7 +1,4 @@
getValue();
- $fileGap = Setting::getSetting('file-gap')->getValue();
- $fileFirst = Setting::getSetting('file-first-number')->getValue();
- $fileQuantity = Setting::getSetting('file-quantity');
$fileUploader = FileUploader::getInstance();
$fileUploader->setMaxSize($maxSize);
@@ -121,13 +115,10 @@ abstract class Controller {
$imagePaths = [];
$url = Setting::getSetting('url')->getValue();
for($i=0;$i<$totalImages;$i++) {
- $fileUploader->setGeneratorValues($fileGap, $fileFirst, $fileQuantity->getValue());
$fileUploader->upload("image_$i");
$imagePaths[] = $url . '/api/system/download?file=' . $fileUploader->getFileName();
- $fileQuantity->value++;
}
- $fileQuantity->store();
return $imagePaths;
}
@@ -138,17 +129,11 @@ abstract class Controller {
if(!isset($_FILES['file'])) return '';
$maxSize = Setting::getSetting('max-size')->getValue();
- $fileGap = Setting::getSetting('file-gap')->getValue();
- $fileFirst = Setting::getSetting('file-first-number')->getValue();
- $fileQuantity = Setting::getSetting('file-quantity');
$fileUploader = FileUploader::getInstance();
$fileUploader->setMaxSize($maxSize);
- $fileUploader->setGeneratorValues($fileGap, $fileFirst, $fileQuantity->getValue());
if($fileUploader->upload('file')) {
- $fileQuantity->value++;
- $fileQuantity->store();
return $fileUploader;
} else {
diff --git a/server/libs/DataStoreList.php b/server/libs/DataStoreList.php
index da995595..37e93687 100755
--- a/server/libs/DataStoreList.php
+++ b/server/libs/DataStoreList.php
@@ -1,16 +1,14 @@
add(new $type($bean));
}
-
+
return $dataStoreList;
}
@@ -51,21 +49,21 @@ class DataStoreList implements IteratorAggregate {
public function toBeanList() {
$beanList = [];
-
+
foreach($this->list as $item) {
$item->updateBeanProperties();
$beanList[] = $item->getBeanInstance();
}
-
+
return $beanList;
}
-
- public function toArray() {
+
+ public function toArray($minimized = false) {
$array = [];
foreach($this->list as $item) {
$item->updateBeanProperties();
- $array[] = $item->toArray();
+ $array[] = $item->toArray($minimized);
}
return $array;
@@ -80,4 +78,4 @@ class DataStoreList implements IteratorAggregate {
return -1;
}
-}
\ No newline at end of file
+}
diff --git a/server/libs/Date.php b/server/libs/Date.php
index 7705ce7e..da033024 100755
--- a/server/libs/Date.php
+++ b/server/libs/Date.php
@@ -7,4 +7,8 @@ class Date {
public static function getPreviousDate($days = 1) {
return date('YmdHi', strtotime(" -$days day "));
}
+
+ public static function getNextDate($days = 1) {
+ return date('YmdHi', strtotime(" +$days day "));
+ }
}
diff --git a/server/libs/FileUploader.php b/server/libs/FileUploader.php
index 9af41d61..382e25d4 100755
--- a/server/libs/FileUploader.php
+++ b/server/libs/FileUploader.php
@@ -2,8 +2,6 @@
class FileUploader extends FileManager {
private $maxSize = 1;
- private $linearCongruentialGenerator;
- private $linearCongruentialGeneratorOffset;
private $fileName;
private $permission;
private $storage;
@@ -61,12 +59,10 @@ class FileUploader extends FileManager {
$newName = preg_replace('/[^a-zA-Z0-9\d\.\-]/', '_', $newName);
$result = "";
- if ($this->linearCongruentialGenerator instanceof LinearCongruentialGenerator) {
- if($this->permission) $result = $this->permission . '_';
- else $result = '';
+ if($this->permission) $result = $this->permission . '_';
+ else $result = '';
- $result .= $this->linearCongruentialGenerator->generate($this->linearCongruentialGeneratorOffset) . '_' . $newName;
- }
+ $result .= substr(Hashing::generateRandomToken(), 0, 6) . '_' . $newName;
return $result;
}
@@ -82,14 +78,6 @@ class FileUploader extends FileManager {
else $this->permission = '';
}
- public function setGeneratorValues($gap, $first, $offset) {
- $this->linearCongruentialGenerator = new LinearCongruentialGenerator();
- $this->linearCongruentialGeneratorOffset = $offset;
-
- $this->linearCongruentialGenerator->setGap($gap);
- $this->linearCongruentialGenerator->setFirst($first);
- }
-
public function setMaxSize($maxSize) {
$this->maxSize = $maxSize;
}
diff --git a/server/libs/MailSender.php b/server/libs/MailSender.php
index 1f0b9c7b..3e336dd2 100755
--- a/server/libs/MailSender.php
+++ b/server/libs/MailSender.php
@@ -26,10 +26,13 @@ class MailSender {
}
public function setTemplate($type, $config) {
- $mailTemplate = MailTemplate::getTemplate($type);
- $compiledMailContent = $mailTemplate->compile($config);
+ $mailTemplate = MailTemplate::getMailTemplate($type);
- $this->mailOptions = array_merge($this->mailOptions, $compiledMailContent);
+ $this->mailOptions = array_merge($this->mailOptions, [
+ 'subject' => $mailTemplate->getSubject($config),
+ 'body' => $mailTemplate->getBody($config),
+ 'to' => $config['to'],
+ ]);
}
public function send() {
diff --git a/server/libs/Validator.php b/server/libs/Validator.php
index 5ac3fbee..0f107c9a 100755
--- a/server/libs/Validator.php
+++ b/server/libs/Validator.php
@@ -1,6 +1,4 @@
_bean->withCondition($condition, $values));
+ }
+
+ public function countShared($shared) {
+ return $this->_bean->countShared($shared);
+ }
+
private function updateBeanProp($key, $value) {
if ($value instanceof DataStoreList) {
$this->_bean[$key] = $value->toBeanList();
diff --git a/server/models/MailTemplate.php b/server/models/MailTemplate.php
index bbb6507b..bb9eb0b3 100755
--- a/server/models/MailTemplate.php
+++ b/server/models/MailTemplate.php
@@ -8,7 +8,9 @@ use RedBeanPHP\Facade as RedBean;
* @apiParam {String} type The type of the mail template.
* @apiParam {String} subject The subject of the mail template.
* @apiParam {string} language The language of the mail template.
- * @apiParam {String} body The body of the mail template.
+ * @apiParam {String} text1 First paragraph of the mail template.
+ * @apiParam {String} text2 Second paragraph of the mail template.
+ * @apiParam {String} text3 Thrid paragraph of the mail template.
*/
class MailTemplate extends DataStore {
@@ -24,11 +26,26 @@ class MailTemplate extends DataStore {
const TICKET_CLOSED = 'TICKET_CLOSED';
const TICKET_CREATED_STAFF = 'TICKET_CREATED_STAFF';
- public static function getTemplate($type) {
+ public static function getFilePaths() {
+ return [
+ 'USER_SIGNUP' => 'data/mail-templates/user-signup.html',
+ 'USER_PASSWORD' => 'data/mail-templates/user-edit-password.html',
+ 'USER_EMAIL' => 'data/mail-templates/user-edit-email.html',
+ 'PASSWORD_FORGOT' => 'data/mail-templates/user-password-forgot.html',
+ 'USER_SYSTEM_DISABLED' => 'data/mail-templates/user-system-disabled.html',
+ 'USER_SYSTEM_ENABLED' => 'data/mail-templates/user-system-enabled.html',
+ 'TICKET_CREATED' => 'data/mail-templates/ticket-created.html',
+ 'TICKET_RESPONDED' => 'data/mail-templates/ticket-responded.html',
+ 'TICKET_CLOSED' => 'data/mail-templates/ticket-closed.html',
+ 'TICKET_CREATED_STAFF' => 'data/mail-templates/ticket-created-staff.html',
+ ];
+ }
+
+ public static function getMailTemplate($template) {
$globalLanguage = Setting::getSetting('language')->value;
- $bean = RedBean::findOne(MailTemplate::TABLE, 'type = :type AND language = :language', array(
- ':type' => $type,
+ $bean = RedBean::findOne(MailTemplate::TABLE, 'template = :template AND language = :language', array(
+ ':template' => $template,
':language' => $globalLanguage
));
@@ -37,19 +54,36 @@ class MailTemplate extends DataStore {
public static function getProps() {
return [
- 'type',
+ 'template',
'subject',
'language',
- 'body'
+ 'text1',
+ 'text2',
+ 'text3',
];
}
- public function compile($config) {
- return [
- 'body' => $this->compileString($this->body, $config),
- 'subject' => $this->compileString($this->subject, $config),
- 'to' => $config['to']
- ];
+ public function getSubject($config) {
+ return $this->compileString($this->subject, $config);
+ }
+
+ public function getBody($config) {
+ $templateFilePaths = MailTemplate::getFilePaths();
+ $texts = [
+ $this->text1, $this->text2, $this->text3, $this->text4,
+ ];
+
+ $matches = [];
+ foreach($texts as $key => $val) {
+ $matches[] = '{{' . $this->template . '_MATCH_' . ($key + 1) . '}}';
+ }
+
+ $matches[] = '{{IMAGE_HEADER_URL}}';
+ $texts[] = Setting::getSetting('mail-template-header-image')->value;
+
+ $body = str_replace($matches, $texts, file_get_contents($templateFilePaths[$this->template]));
+
+ return $this->compileString($body, $config);
}
public function compileString($string, $config) {
@@ -61,12 +95,15 @@ class MailTemplate extends DataStore {
return $compiledString;
}
+
public function toArray() {
return [
- 'type' => $this->type,
+ 'template' => $this->template,
'subject' => $this->subject,
'language' => $this->language,
- 'body' => $this->body,
+ 'text1' => $this->text1,
+ 'text2' => $this->text2,
+ 'text3' => $this->text3,
];
}
}
diff --git a/server/models/Ticket.php b/server/models/Ticket.php
index 9e7819bf..40597a44 100755
--- a/server/models/Ticket.php
+++ b/server/models/Ticket.php
@@ -96,25 +96,25 @@ class Ticket extends DataStore {
public function generateUniqueTicketNumber() {
$linearCongruentialGenerator = new LinearCongruentialGenerator();
- $ticketQuantity = Ticket::count();
- if ($ticketQuantity === 0) {
+ if (Ticket::count() === 0) {
$ticketNumber = Setting::getSetting('ticket-first-number')->value;
} else {
+ $lastTicketId = Ticket::findOne(' ORDER BY id DESC')->id;
$linearCongruentialGenerator->setGap(Setting::getSetting('ticket-gap')->value);
$linearCongruentialGenerator->setFirst(Setting::getSetting('ticket-first-number')->value);
- $ticketNumber = $linearCongruentialGenerator->generate($ticketQuantity);
+ $ticketNumber = $linearCongruentialGenerator->generate($lastTicketId + 1);
}
return $ticketNumber;
}
- public function toArray() {
+ public function toArray($minimized = false) {
return [
'ticketNumber' => $this->ticketNumber,
'title' => $this->title,
- 'content' => $this->content,
+ 'content' => $minimized ? strip_tags($this->content) : $this->content,
'department' => [
'id' => $this->department->id,
'name' => $this->department->name
@@ -128,7 +128,7 @@ class Ticket extends DataStore {
'priority' => $this->priority,
'author' => $this->authorToArray(),
'owner' => $this->ownerToArray(),
- 'events' => $this->eventsToArray()
+ 'events' => $minimized ? [] : $this->eventsToArray()
];
}
diff --git a/server/tests/__mocks__/RedBeanMock.php b/server/tests/__mocks__/RedBeanMock.php
index 1abb5f50..4fe832bc 100755
--- a/server/tests/__mocks__/RedBeanMock.php
+++ b/server/tests/__mocks__/RedBeanMock.php
@@ -10,6 +10,7 @@ namespace RedBeanPHP {
self::setStatics(array(
'trash' => parent::stub(),
'store' => parent::stub(),
+ 'exec' => parent::stub(),
'dispense' => parent::stub()->returns(new \BeanMock())
));
}
diff --git a/server/tests/controllers/user/loginTest.php b/server/tests/controllers/user/loginTest.php
index f86ec8b6..035aaa70 100755
--- a/server/tests/controllers/user/loginTest.php
+++ b/server/tests/controllers/user/loginTest.php
@@ -8,10 +8,9 @@ include_once 'tests/__mocks__/SessionMock.php';
include_once 'tests/__mocks__/UserMock.php';
include_once 'tests/__mocks__/HashingMock.php';
include_once 'tests/__mocks__/SessionCookieMock.php';
+include_once 'tests/__mocks__/RedBeanMock.php';
include_once 'data/ERRORS.php';
-include_once 'controllers/user/login.php';
-
use PHPUnit\Framework\TestCase;
class LoginControllerTest extends TestCase {
@@ -45,7 +44,8 @@ class LoginControllerTest extends TestCase {
'userEmail' => 'MOCK_EMAIL',
'staff' => false,
'token' => 'TEST_TOKEN',
- 'rememberToken' => null
+ 'rememberToken' => null,
+ 'rememberExpiration' => Date::getNextDate(30)
)));
}
diff --git a/server/tests/libs/HashingTest.php b/server/tests/libs/HashingTest.php
index 9b4cfb95..4d8de399 100644
--- a/server/tests/libs/HashingTest.php
+++ b/server/tests/libs/HashingTest.php
@@ -1,6 +1,4 @@
assertFalse(Hashing::isPrime($number));
}
- public function testShouldGenerateRandsomPrime() {
+ public function testShouldGenerateRandomPrime() {
$TEST_TIMES = 10;
for ($i = 0; $i < $TEST_TIMES; $i++) {
@@ -65,7 +63,6 @@ class HashingTest extends TestCase {
$this->assertTrue($min < $number1 && $number1 < $max);
$this->assertTrue($min < $number2 && $number2 < $max);
- $this->assertNotEquals($number1, $number2);
$this->assertTrue(Hashing::isPrime($number1));
$this->assertTrue(Hashing::isPrime($number2));
}
diff --git a/server/tests/libs/LinearCongruentialGeneratorTest.php b/server/tests/libs/LinearCongruentialGeneratorTest.php
index f2f29410..5d5f671f 100644
--- a/server/tests/libs/LinearCongruentialGeneratorTest.php
+++ b/server/tests/libs/LinearCongruentialGeneratorTest.php
@@ -1,7 +1,4 @@
assertEquals('TEST_TYPE', $mailTemplate->type);
- $this->assertTrue(Redbean::get('findOne')->hasBeenCalledWithArgs('mailtemplate', 'type = :type AND language = :language', array(
- ':type' => 'USER_SIGNUP',
+ $this->assertEquals('USER_SIGNUP', $mailTemplate->type);
+ $this->assertTrue(Redbean::get('findOne')->hasBeenCalledWithArgs('mailtemplate', 'template = :template AND language = :language', array(
+ ':template' => 'USER_SIGNUP',
':language' => 'MOCK_SETTING_VALUE'
)));
}
@@ -32,23 +31,31 @@ class MailTemplateTest extends TestCase {
public function testCompilation() {
$mailTemplate = new MailTemplate();
$mailTemplate->setProperties([
+ 'template' => 'USER_SIGNUP',
'subject' => 'Welcoming to {{to}}',
- 'body' => 'Welcome, {{userName}} to our team'
+ 'text1' => 'Welcome, {{userName}} to our team'
]);
- $result = $mailTemplate->compile([
+ $resultSubject = $mailTemplate->getSubject([
'to' => 'cersei@opensupports.com',
'userName' => 'Cersei Lannister',
]);
- $this->assertEquals($result['subject'], 'Welcoming to cersei@opensupports.com');
- $this->assertEquals($result['body'], 'Welcome, Cersei Lannister to our team');
+ $resultBody = $mailTemplate->getBody([
+ 'to' => 'cersei@opensupports.com',
+ 'userName' => 'Cersei Lannister',
+ ]);
+
+ $this->assertEquals($resultSubject, 'Welcoming to cersei@opensupports.com');
+ $this->assertContains('Welcome, Cersei Lannister to our team', $resultBody);
}
private function getMockTemplateBean() {
$mailTemplateBean = new BeanMock();
- $mailTemplateBean->type = 'TEST_TYPE';
- $mailTemplateBean->body = 'Some body';
+ $mailTemplateBean->type = 'USER_SIGNUP';
+ $mailTemplateBean->text1 = 'Text1';
+ $mailTemplateBean->text2 = 'Text1';
+ $mailTemplateBean->text3 = 'Text1';
$mailTemplateBean->subject = 'Some subject';
$mailTemplateBean->language = 'en';
diff --git a/server/tests/models/ResponseTest.php b/server/tests/models/ResponseTest.php
index 567766fe..89888e78 100755
--- a/server/tests/models/ResponseTest.php
+++ b/server/tests/models/ResponseTest.php
@@ -1,7 +1,6 @@