+
);
diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js
index 87eebb71..d1d9548d 100644
--- a/client/src/data/languages/en.js
+++ b/client/src/data/languages/en.js
@@ -349,5 +349,6 @@ export default {
'ACTIVITY_RE_OPEN_THIS': 'reopened this ticket',
'ACTIVITY_DEPARTMENT_CHANGED_THIS': 'changed department of this ticket to ',
'ACTIVITY_PRIORITY_CHANGED_THIS': 'changed priority of this ticket to',
- 'DATE_PREFIX': 'on'
+ 'DATE_PREFIX': 'on',
+ 'LEFT_EMPTY_DATABASE': 'Left empty for automatic database creation'
};
diff --git a/client/src/index.html b/client/src/index.html
index 04d3e7f6..8271ea09 100644
--- a/client/src/index.html
+++ b/client/src/index.html
@@ -1,22 +1,21 @@
-
-
-
-
-
+
+
+
+
+
-
OS4
+
OpenSupports
-
-
-
-
+
+
+
+
-
+
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/client/src/index.js b/client/src/index.js
index 64ed5b84..e5b95387 100644
--- a/client/src/index.js
+++ b/client/src/index.js
@@ -37,5 +37,6 @@ let unsubscribe = store.subscribe(() => {
}
});
+store.dispatch(ConfigActions.checkInstallation());
store.dispatch(ConfigActions.init());
store.dispatch(SessionActions.initSession());
diff --git a/client/src/index.php b/client/src/index.php
new file mode 100644
index 00000000..c73e539e
--- /dev/null
+++ b/client/src/index.php
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
OpenSupports
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/src/lib-app/session-store.js b/client/src/lib-app/session-store.js
index 645e5ff8..d5d1086a 100644
--- a/client/src/lib-app/session-store.js
+++ b/client/src/lib-app/session-store.js
@@ -69,7 +69,7 @@ class SessionStore {
return {
language: this.getItem('language'),
reCaptchaKey: this.getItem('reCaptchaKey'),
- departments: this.getDepartments(),
+ departments: this.getDepartments() || [],
allowedLanguages: JSON.parse(this.getItem('allowedLanguages')),
supportedLanguages: JSON.parse(this.getItem('supportedLanguages')),
layout: this.getItem('layout'),
@@ -110,7 +110,7 @@ class SessionStore {
}
setItem(key, value) {
- return this.storage.setItem(key, value);
+ return this.storage.setItem(key, (value !== undefined) ? value : '');
}
removeItem(key) {
diff --git a/client/src/reducers/config-reducer.js b/client/src/reducers/config-reducer.js
index d3861851..91928810 100644
--- a/client/src/reducers/config-reducer.js
+++ b/client/src/reducers/config-reducer.js
@@ -8,7 +8,9 @@ class ConfigReducer extends Reducer {
getInitialState() {
return {
language: sessionStore.getItem('language'),
- initDone: false
+ initDone: false,
+ installedDone: false,
+ installed: false
};
}
@@ -16,6 +18,7 @@ class ConfigReducer extends Reducer {
return {
'CHANGE_LANGUAGE': this.onLanguageChange,
'INIT_CONFIGS_FULFILLED': this.onInitConfigs,
+ 'CHECK_INSTALLATION_FULFILLED': this.onInstallationChecked,
'UPDATE_DATA_FULFILLED': this.onInitConfigs
};
}
@@ -44,6 +47,13 @@ class ConfigReducer extends Reducer {
initDone: true
});
}
+
+ onInstallationChecked(state, payload) {
+ return _.extend({}, state, {
+ installedDone: true,
+ installed: payload.data
+ });
+ }
}
export default ConfigReducer.getInstance();
\ No newline at end of file
diff --git a/server/controllers/staff/edit.php b/server/controllers/staff/edit.php
index 6bc3f7e1..eaf8839a 100644
--- a/server/controllers/staff/edit.php
+++ b/server/controllers/staff/edit.php
@@ -57,7 +57,7 @@ class EditStaffController extends Controller {
$this->staffInstance->sharedDepartmentList = $this->getDepartmentList();
}
- if($fileUploader = $this->uploadFile()) {
+ if($fileUploader = $this->uploadFile(true)) {
$this->staffInstance->profilePic = ($fileUploader instanceof FileUploader) ? $fileUploader->getFileName() : null;
}
diff --git a/server/controllers/staff/get-all-tickets.php b/server/controllers/staff/get-all-tickets.php
index 98c3f4d6..44350d2d 100644
--- a/server/controllers/staff/get-all-tickets.php
+++ b/server/controllers/staff/get-all-tickets.php
@@ -18,6 +18,13 @@ class GetAllTicketsStaffController extends Controller {
}
public function handler() {
+ if (Ticket::isTableEmpty()) {
+ Response::respondSuccess([
+ 'tickets' => [],
+ 'pages' => 0
+ ]);
+ return;
+ }
Response::respondSuccess([
'tickets' => $this->getTicketList()->toArray(),
diff --git a/server/controllers/staff/get-new-tickets.php b/server/controllers/staff/get-new-tickets.php
index bc2e5ca8..67f631db 100644
--- a/server/controllers/staff/get-new-tickets.php
+++ b/server/controllers/staff/get-new-tickets.php
@@ -13,6 +13,11 @@ class GetNewTicketsStaffController extends Controller {
];
}
public function handler() {
+ if (Ticket::isTableEmpty()) {
+ Response::respondSuccess([]);
+ return;
+ }
+
$user = Controller::getLoggedUser();
$query = ' (';
foreach ($user->sharedDepartmentList as $department) {
diff --git a/server/controllers/system/check-requirements.php b/server/controllers/system/check-requirements.php
index 81a07d52..855470f6 100644
--- a/server/controllers/system/check-requirements.php
+++ b/server/controllers/system/check-requirements.php
@@ -14,6 +14,8 @@ class CheckRequirementsController extends Controller {
}
public function handler() {
+ $configWritable = !!fopen('config.php', 'w+');
+
Response::respondSuccess([
'phpVersion' => [
'name' => 'PHP Version',
@@ -32,8 +34,8 @@ class CheckRequirementsController extends Controller {
],
'files' => [
'name' => 'Folder: /api/files',
- 'value' => is_writable('files/') ? 'Writable' : 'Not writable',
- 'ok' => is_writable('files/')
+ 'value' => $configWritable ? 'Writable' : 'Not writable',
+ 'ok' => $configWritable
]
]);
}
diff --git a/server/controllers/system/get-settings.php b/server/controllers/system/get-settings.php
index 15f1df8d..8b3a1be2 100644
--- a/server/controllers/system/get-settings.php
+++ b/server/controllers/system/get-settings.php
@@ -12,44 +12,47 @@ class GetSettingsController extends Controller {
}
public function handler() {
+ $settingsList = [];
- if(Controller::request('allSettings') && Controller::isStaffLogged(3)) {
- $settingsList = [
- 'language' => Setting::getSetting('language')->getValue(),
- 'reCaptchaKey' => Setting::getSetting('recaptcha-public')->getValue(),
- 'reCaptchaPrivate' => Setting::getSetting('recaptcha-private')->getValue(),
- 'time-zone' => Setting::getSetting('time-zone')->getValue(),
- 'maintenance-mode' => Setting::getSetting('maintenance-mode')->getValue(),
- 'layout' => Setting::getSetting('layout')->getValue(),
- 'allow-attachments' => Setting::getSetting('allow-attachments')->getValue(),
- 'max-size' => Setting::getSetting('max-size')->getValue(),
- 'url' => Setting::getSetting('url')->getValue(),
- 'title' => Setting::getSetting('title')->getValue(),
- 'no-reply-email' => Setting::getSetting('no-reply-email')->getValue(),
- 'smtp-port' => Setting::getSetting('smtp-port')->getValue(),
- 'smtp-host' => Setting::getSetting('smtp-host')->getValue(),
- 'smtp-user' => Setting::getSetting('smtp-user')->getValue(),
- 'registration' => Setting::getSetting('registration')->getValue(),
- 'departments' => Department::getDepartmentNames(),
- 'supportedLanguages' => Language::getSupportedLanguages(),
- 'allowedLanguages' => Language::getAllowedLanguages()
- ];
- } else {
- $settingsList = [
- 'language' => Setting::getSetting('language')->getValue(),
- 'reCaptchaKey' => Setting::getSetting('recaptcha-public')->getValue(),
- 'time-zone' => Setting::getSetting('time-zone')->getValue(),
- 'maintenance-mode' => Setting::getSetting('maintenance-mode')->getValue(),
- 'layout' => Setting::getSetting('layout')->getValue(),
- 'allow-attachments' => Setting::getSetting('allow-attachments')->getValue(),
- 'max-size' => Setting::getSetting('max-size')->getValue(),
- 'title' => Setting::getSetting('title')->getValue(),
- 'registration' => Setting::getSetting('registration')->getValue(),
- 'departments' => Department::getDepartmentNames(),
- 'supportedLanguages' => Language::getSupportedLanguages(),
- 'allowedLanguages' => Language::getAllowedLanguages(),
- 'user-system-enabled' => Setting::getSetting('user-system-enabled')->getValue()
- ];
+ if(InstallationDoneController::isInstallationDone()) {
+ if(Controller::request('allSettings') && Controller::isStaffLogged(3)) {
+ $settingsList = [
+ 'language' => Setting::getSetting('language')->getValue(),
+ 'reCaptchaKey' => Setting::getSetting('recaptcha-public')->getValue(),
+ 'reCaptchaPrivate' => Setting::getSetting('recaptcha-private')->getValue(),
+ 'time-zone' => Setting::getSetting('time-zone')->getValue(),
+ 'maintenance-mode' => Setting::getSetting('maintenance-mode')->getValue() * 1,
+ 'layout' => Setting::getSetting('layout')->getValue(),
+ 'allow-attachments' => Setting::getSetting('allow-attachments')->getValue() * 1,
+ 'max-size' => Setting::getSetting('max-size')->getValue(),
+ 'url' => Setting::getSetting('url')->getValue(),
+ 'title' => Setting::getSetting('title')->getValue(),
+ 'no-reply-email' => Setting::getSetting('no-reply-email')->getValue(),
+ 'smtp-port' => Setting::getSetting('smtp-port')->getValue(),
+ 'smtp-host' => Setting::getSetting('smtp-host')->getValue(),
+ 'smtp-user' => Setting::getSetting('smtp-user')->getValue(),
+ 'registration' => Setting::getSetting('registration')->getValue(),
+ 'departments' => Department::getDepartmentNames(),
+ 'supportedLanguages' => Language::getSupportedLanguages(),
+ 'allowedLanguages' => Language::getAllowedLanguages()
+ ];
+ } else {
+ $settingsList = [
+ 'language' => Setting::getSetting('language')->getValue(),
+ 'reCaptchaKey' => Setting::getSetting('recaptcha-public')->getValue(),
+ 'time-zone' => Setting::getSetting('time-zone')->getValue(),
+ 'maintenance-mode' => Setting::getSetting('maintenance-mode')->getValue() * 1,
+ 'layout' => Setting::getSetting('layout')->getValue(),
+ 'allow-attachments' => Setting::getSetting('allow-attachments')->getValue() * 1,
+ 'max-size' => Setting::getSetting('max-size')->getValue(),
+ 'title' => Setting::getSetting('title')->getValue(),
+ 'registration' => Setting::getSetting('registration')->getValue(),
+ 'departments' => Department::getDepartmentNames(),
+ 'supportedLanguages' => Language::getSupportedLanguages(),
+ 'allowedLanguages' => Language::getAllowedLanguages(),
+ 'user-system-enabled' => Setting::getSetting('user-system-enabled')->getValue() * 1
+ ];
+ }
}
Response::respondSuccess($settingsList);
diff --git a/server/controllers/system/init-database.php b/server/controllers/system/init-database.php
index 73d539be..a360bff5 100644
--- a/server/controllers/system/init-database.php
+++ b/server/controllers/system/init-database.php
@@ -14,17 +14,43 @@ class InitDatabaseController extends Controller {
}
public function handler() {
- if(defined('MYSQL_HOST')) {
+ if(InstallationDoneController::isInstallationDone()) {
throw new Exception(ERRORS::INIT_SETTINGS_DONE);
- return;
+ }
+
+ $dbHost = Controller::request('dbHost');
+ $dbName = Controller::request('dbName');
+ $dbUser = Controller::request('dbUser');
+ $dbPass = Controller::request('dbPassword');
+
+ if(!defined('MYSQL_HOST')) {
+ RedBean::setup('mysql:host=' . $dbHost, $dbUser, $dbPass);
+ }
+
+ if($dbName) {
+ RedBean::addDatabase($dbName, 'mysql:host='. $dbHost . ';dbname=' . $dbName, $dbUser, $dbPass);
+ RedBean::selectDatabase($dbName);
+
+ if(!RedBean::testConnection()) {
+ throw new Exception(ERRORS::DATABASE_CONNECTION);
+ }
+ } else {
+ $dbName = 'opensupports_' . Hashing::generateRandomNumber(100, 999);
+ RedBean::exec('CREATE DATABASE ' . $dbName);
+ RedBean::addDatabase($dbName, 'mysql:host='. $dbHost . ';dbname=' . $dbName, $dbUser, $dbPass);
+ RedBean::selectDatabase($dbName);
+
+ if(!RedBean::testConnection()) {
+ throw new Exception(ERRORS::DATABASE_CREATION);
+ }
}
$configFile = fopen('config.php', 'w+') or die(ERRORS::INVALID_FILE);
$content = ' !!Controller::request('registration'),
'user-system-enabled' => !!Controller::request('user-system-enabled'),
'last-stat-day' => date('YmdHi', strtotime(' -12 day ')),
- 'ticket-gap' => Hashing::generateRandomPrime(100000, 999999),
- 'file-gap' => Hashing::generateRandomPrime(100000, 999999),
- 'file-first-number' => Hashing::generateRandomNumber(100000, 999999),
+ 'ticket-gap' => Hashing::generateRandomPrime(1000000, 9999999),
+ 'file-gap' => Hashing::generateRandomPrime(1000000, 9999999),
+ 'file-first-number' => Hashing::generateRandomNumber(1000000, 9999999),
'file-quantity' => 0
]);
}
diff --git a/server/controllers/system/installation-done.php b/server/controllers/system/installation-done.php
index 64f52386..ace2d667 100644
--- a/server/controllers/system/installation-done.php
+++ b/server/controllers/system/installation-done.php
@@ -5,6 +5,10 @@ class InstallationDoneController extends Controller {
const PATH = '/installation-done';
const METHOD = 'POST';
+ public static function isInstallationDone() {
+ return RedBean::testConnection() && !Setting::isTableEmpty() && !Staff::isTableEmpty();
+ }
+
public function validations() {
return [
'permission' => 'any',
@@ -13,7 +17,7 @@ class InstallationDoneController extends Controller {
}
public function handler() {
- if(RedBean::testConnection() && !Setting::isTableEmpty() && !Staff::isTableEmpty()) {
+ if(InstallationDoneController::isInstallationDone()) {
Response::respondSuccess(1);
} else {
Response::respondSuccess(0);
diff --git a/server/controllers/ticket/comment.php b/server/controllers/ticket/comment.php
index 5f401d85..333b6eb8 100644
--- a/server/controllers/ticket/comment.php
+++ b/server/controllers/ticket/comment.php
@@ -99,8 +99,8 @@ class CommentController extends Controller {
$mailSender = new MailSender();
$mailSender->setTemplate(MailTemplate::TICKET_RESPONDED, [
- 'to' => $this->ticket->author->email,
- 'name' => $this->ticket->author->name,
+ 'to' => ($this->ticket->author) ? $this->ticket->author->email : $this->ticket->authorEmail,
+ 'name' => ($this->ticket->author) ? $this->ticket->author->name : $this->ticket->authorName,
'ticketNumber' => $this->ticket->ticketNumber,
'title' => $this->ticket->title,
'url' => Setting::getSetting('url')->getValue()
diff --git a/server/data/ERRORS.php b/server/data/ERRORS.php
index d75c7e2b..22f2291b 100644
--- a/server/data/ERRORS.php
+++ b/server/data/ERRORS.php
@@ -41,4 +41,6 @@ class ERRORS {
const INVALID_PERIOD = 'INVALID_PERIOD';
const NAME_ALREADY_USED = 'NAME_ALREADY_USED';
const INVALID_FILE = 'INVALID_FILE';
+ const DATABASE_CONNECTION = 'DATABASE_CONNECTION';
+ const DATABASE_CREATION = 'DATABASE_CREATION';
}
diff --git a/server/index.php b/server/index.php
index e8eb2c4d..083cb613 100644
--- a/server/index.php
+++ b/server/index.php
@@ -1,5 +1,5 @@
validate();
$this->handler();
} catch (\Exception $exception) {
- Response::respondError($exception->getMessage());
+ Response::respondError($exception->getMessage() . ' on line ' . $exception->getFile() . ':' . $exception->getLine());
return;
}
};
diff --git a/server/models/Ticketevent.php b/server/models/Ticketevent.php
index a8a23fed..c178d349 100644
--- a/server/models/Ticketevent.php
+++ b/server/models/Ticketevent.php
@@ -60,15 +60,15 @@ class Ticketevent extends DataStore {
}
public function toArray() {
- $user = ($this->authorUser instanceof User) ? $this->authorUser : $this->authorStaff;
+ $user = ($this->authorStaff) ? $this->authorStaff : $this->authorUser;
return [
'type' => $this->type,
'ticketNumber' => $this->ticket->ticketNumber,
'author' => [
- 'name' => $user->name,
+ 'name' => $user ? $user->name : null,
'staff' => $user instanceOf Staff,
- 'id' => $user->id
+ 'id' => $user ? $user->id : null
]
];
}