mirror of
https://github.com/opensupports/opensupports.git
synced 2025-04-08 18:35:06 +02:00
feat: add dist
This commit is contained in:
parent
320227815f
commit
b5e3316040
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,4 +8,6 @@ server/files/
|
||||
server/.dbdata
|
||||
server/.fakemail
|
||||
server/apidoc
|
||||
database/
|
||||
config/
|
||||
.env
|
||||
|
0
client/src/assets/images/icon.png
Normal file → Executable file
0
client/src/assets/images/icon.png
Normal file → Executable file
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
0
client/src/assets/images/logo.png
Normal file → Executable file
0
client/src/assets/images/logo.png
Normal file → Executable file
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
0
client/src/assets/images/profile.png
Normal file → Executable file
0
client/src/assets/images/profile.png
Normal file → Executable file
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
5
dist/.htaccess
vendored
Executable file
5
dist/.htaccess
vendored
Executable file
@ -0,0 +1,5 @@
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} !^/?(api)/
|
||||
RewriteRule .* index.php [PT,L]
|
4
dist/api/.htaccess
vendored
Executable file
4
dist/api/.htaccess
vendored
Executable file
@ -0,0 +1,4 @@
|
||||
RewriteEngine on
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule .* index.php [PT,L]
|
20
dist/api/composer.json
vendored
Executable file
20
dist/api/composer.json
vendored
Executable file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"require": {
|
||||
"slim/slim": "~2.0",
|
||||
"respect/validation": "^1.1",
|
||||
"phpmailer/phpmailer": "^5.2",
|
||||
"google/recaptcha": "~1.1",
|
||||
"gabordemooij/redbean": "^5.4",
|
||||
"ifsnop/mysqldump-php": "2.*",
|
||||
"ezyang/htmlpurifier": "^4.8",
|
||||
"codeguy/upload": "^1.3",
|
||||
"php-imap/php-imap": "^3.1",
|
||||
"willdurand/email-reply-parser": "^2.8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7"
|
||||
},
|
||||
"autoload":{
|
||||
"classmap": ["libs/", "models/", "controllers/", "data/"]
|
||||
}
|
||||
}
|
2062
dist/api/composer.lock
generated
vendored
Executable file
2062
dist/api/composer.lock
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
0
dist/api/config.php
vendored
Executable file
0
dist/api/config.php
vendored
Executable file
13
dist/api/controllers/article.php
vendored
Executable file
13
dist/api/controllers/article.php
vendored
Executable file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
$articleControllers = new ControllerGroup();
|
||||
$articleControllers->setGroupPath('/article');
|
||||
|
||||
$articleControllers->addController(new AddTopicController);
|
||||
$articleControllers->addController(new EditTopicController);
|
||||
$articleControllers->addController(new DeleteTopicController);
|
||||
$articleControllers->addController(new AddArticleController);
|
||||
$articleControllers->addController(new EditArticleController);
|
||||
$articleControllers->addController(new DeleteArticleController);
|
||||
$articleControllers->addController(new GetAllArticlesController);
|
||||
|
||||
$articleControllers->finalize();
|
61
dist/api/controllers/article/add-topic.php
vendored
Executable file
61
dist/api/controllers/article/add-topic.php
vendored
Executable file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /article/add-topic Add topic
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Add topic
|
||||
*
|
||||
* @apiGroup Article
|
||||
*
|
||||
* @apiDescription This path adds a new topic.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {String} name Name of the new topic.
|
||||
* @apiParam {String} icon Icon of the new topic.
|
||||
* @apiParam {String} iconColor Icon's color of the new topic.
|
||||
* @apiParam {Boolean} private Indicates if the topic is not shown to users.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
*
|
||||
* @apiSuccess {Object} data Topic info
|
||||
* @apiSuccess {Number} data.topicId Topic id
|
||||
*
|
||||
*/
|
||||
|
||||
class AddTopicController extends Controller {
|
||||
const PATH = '/add-topic';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$topic = new Topic();
|
||||
$topic->setProperties([
|
||||
'name' => Controller::request('name', true),
|
||||
'icon' => Controller::request('icon'),
|
||||
'iconColor' => Controller::request('iconColor'),
|
||||
'private' => Controller::request('private') ? 1 : 0
|
||||
]);
|
||||
|
||||
Log::createLog('ADD_TOPIC', $topic->name);
|
||||
|
||||
Response::respondSuccess([
|
||||
'topicId' => $topic->store()
|
||||
]);
|
||||
}
|
||||
}
|
82
dist/api/controllers/article/add.php
vendored
Executable file
82
dist/api/controllers/article/add.php
vendored
Executable file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /article/add Add article
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Add article
|
||||
*
|
||||
* @apiGroup Article
|
||||
*
|
||||
* @apiDescription This path adds a new article.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {String} title Title of the new article.
|
||||
* @apiParam {String} content Content of the new article.
|
||||
* @apiParam {Number} position Position of the new article.
|
||||
* @apiParam {Number} topicId Id of the articles's topic.
|
||||
* @apiParam {Number} images The number of images in the content
|
||||
* @apiParam image_i The image file of index `i` (mutiple params accepted)
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TITLE
|
||||
* @apiUse INVALID_CONTENT
|
||||
* @apiUse INVALID_TOPIC
|
||||
*
|
||||
* @apiSuccess {Object} data Article info
|
||||
* @apiSuccess {Number} data.articleId Article id
|
||||
*/
|
||||
|
||||
class AddArticleController extends Controller {
|
||||
const PATH = '/add';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'title' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TITLE, LengthConfig::MAX_LENGTH_TITLE),
|
||||
'error' => ERRORS::INVALID_TITLE
|
||||
],
|
||||
'content' => [
|
||||
'validation' => DataValidator::content(),
|
||||
'error' => ERRORS::INVALID_CONTENT
|
||||
],
|
||||
'topicId' => [
|
||||
'validation' => DataValidator::dataStoreId('topic'),
|
||||
'error' => ERRORS::INVALID_TOPIC
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$content = Controller::request('content', true);
|
||||
|
||||
$fileUploader = FileUploader::getInstance();
|
||||
$fileUploader->setPermission(FileManager::PERMISSION_ARTICLE);
|
||||
$imagePaths = $this->uploadImages(true);
|
||||
|
||||
$article = new Article();
|
||||
$article->setProperties([
|
||||
'title' => Controller::request('title', true),
|
||||
'content' => $this->replaceWithImagePaths($imagePaths, $content),
|
||||
'lastEdited' => Date::getCurrentDate(),
|
||||
'position' => Controller::request('position') || 1
|
||||
]);
|
||||
|
||||
$topic = Topic::getDataStore(Controller::request('topicId'));
|
||||
$topic->ownArticleList->add($article);
|
||||
$topic->store();
|
||||
|
||||
Log::createLog('ADD_ARTICLE', $article->title);
|
||||
|
||||
Response::respondSuccess([
|
||||
'articleId' => $article->store()
|
||||
]);
|
||||
}
|
||||
}
|
50
dist/api/controllers/article/delete-topic.php
vendored
Executable file
50
dist/api/controllers/article/delete-topic.php
vendored
Executable file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /article/delete-topic Delete topic
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete topic
|
||||
*
|
||||
* @apiGroup Article
|
||||
*
|
||||
* @apiDescription This path deletes a topic.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {Number} topicId Id of the topic.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TOPIC
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteTopicController extends Controller {
|
||||
const PATH = '/delete-topic';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'topicId' => [
|
||||
'validation' => DataValidator::dataStoreId('topic'),
|
||||
'error' => ERRORS::INVALID_TOPIC
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$topic = Topic::getDataStore(Controller::request('topicId'));
|
||||
|
||||
Log::createLog('DELETE_TOPIC', $topic->name);
|
||||
|
||||
$topic->delete();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
50
dist/api/controllers/article/delete.php
vendored
Executable file
50
dist/api/controllers/article/delete.php
vendored
Executable file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /article/delete Delete article
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete article
|
||||
*
|
||||
* @apiGroup Article
|
||||
*
|
||||
* @apiDescription This path deletes an article.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {Number} articleId Id of the article.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TOPIC
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteArticleController extends Controller {
|
||||
const PATH = '/delete';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'articleId' => [
|
||||
'validation' => DataValidator::dataStoreId('article'),
|
||||
'error' => ERRORS::INVALID_TOPIC
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$article = Article::getDataStore(Controller::request('articleId'));
|
||||
Log::createLog('DELETE_ARTICLE', $article->title);
|
||||
|
||||
$article->delete();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
72
dist/api/controllers/article/edit-topic.php
vendored
Executable file
72
dist/api/controllers/article/edit-topic.php
vendored
Executable file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /article/edit-topic Edit topic
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit topic
|
||||
*
|
||||
* @apiGroup Article
|
||||
*
|
||||
* @apiDescription This path edits a topic.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {Number} topicId Id of the topic.
|
||||
* @apiParam {String} name The new name of the topic. Optional.
|
||||
* @apiParam {String} icon The new icon of the topic. Optional.
|
||||
* @apiParam {String} iconColor The new Icon's color of the topic. Optional.
|
||||
* @apiParam {Boolean} private Indicates if the topic is not shown to users.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TOPIC
|
||||
* @apiUse INVALID_NAME
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditTopicController extends Controller {
|
||||
const PATH = '/edit-topic';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'topicId' => [
|
||||
'validation' => DataValidator::dataStoreId('topic'),
|
||||
'error' => ERRORS::INVALID_TOPIC
|
||||
],
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$topic = Topic::getDataStore(Controller::request('topicId'));
|
||||
|
||||
if(Controller::request('name')) {
|
||||
$topic->name = Controller::request('name', true);
|
||||
}
|
||||
|
||||
if(Controller::request('iconColor')) {
|
||||
$topic->iconColor = Controller::request('iconColor');
|
||||
}
|
||||
|
||||
if(Controller::request('icon')) {
|
||||
$topic->icon = Controller::request('icon');
|
||||
}
|
||||
if (Controller::request('private') !== null) {
|
||||
$topic->private = Controller::request('private');
|
||||
}
|
||||
|
||||
$topic->store();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
101
dist/api/controllers/article/edit.php
vendored
Executable file
101
dist/api/controllers/article/edit.php
vendored
Executable file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /article/edit Edit article
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit a article
|
||||
*
|
||||
* @apiGroup Article
|
||||
*
|
||||
* @apiDescription This path edits an article.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {Number} articleId Id of the article.
|
||||
* @apiParam {Number} topicId Id of the topic of the article. Optional.
|
||||
* @apiParam {String} content The new content of the article. Optional.
|
||||
* @apiParam {String} title The new title of the article. Optional.
|
||||
* @apiParam {Number} position The new position of the article. Optional.
|
||||
* @apiParam {Number} images The number of images in the content
|
||||
* @apiParam image_i The image file of index `i` (mutiple params accepted)
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TOPIC
|
||||
* @apiUse INVALID_FILE
|
||||
* @apiUse INVALID_TITLE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditArticleController extends Controller {
|
||||
const PATH = '/edit';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'articleId' => [
|
||||
'validation' => DataValidator::dataStoreId('article'),
|
||||
'error' => ERRORS::INVALID_TOPIC
|
||||
],
|
||||
'title' => [
|
||||
'validation' => DataValidator::oneOf(
|
||||
DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TITLE, LengthConfig::MAX_LENGTH_TITLE),
|
||||
DataValidator::nullType()
|
||||
),
|
||||
'error' => ERRORS::INVALID_TITLE
|
||||
],
|
||||
'content' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::content(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_CONTENT
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$article = Article::getDataStore(Controller::request('articleId'));
|
||||
|
||||
if (Controller::request('topicId')) {
|
||||
$newArticleTopic = Topic::getDataStore(Controller::request('topicId'));
|
||||
|
||||
if (!$newArticleTopic->isNull()) {
|
||||
$article->topic = $newArticleTopic;
|
||||
} else {
|
||||
throw new RequestException(ERRORS::INVALID_TOPIC);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(Controller::request('content')) {
|
||||
$fileUploader = FileUploader::getInstance();
|
||||
$fileUploader->setPermission(FileManager::PERMISSION_ARTICLE);
|
||||
|
||||
$content = Controller::request('content', true);
|
||||
$imagePaths = $this->uploadImages(true);
|
||||
|
||||
$article->content = $this->replaceWithImagePaths($imagePaths, $content);
|
||||
}
|
||||
|
||||
if(Controller::request('title')) {
|
||||
$article->title = Controller::request('title');
|
||||
}
|
||||
|
||||
if(Controller::request('position')) {
|
||||
$article->position = Controller::request('position');
|
||||
}
|
||||
|
||||
$article->lastEdited = Date::getCurrentDate();
|
||||
|
||||
$article->store();
|
||||
|
||||
Log::createLog('EDIT_ARTICLE', $article->title);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
47
dist/api/controllers/article/get-all.php
vendored
Executable file
47
dist/api/controllers/article/get-all.php
vendored
Executable file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /article/get-all Get all articles
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get all articles
|
||||
*
|
||||
* @apiGroup Article
|
||||
*
|
||||
* @apiDescription This path retrieves all the articles.
|
||||
*
|
||||
* @apiPermission any or user
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[Topic](#api-Data_Structures-ObjectTopic)[]} data Array of topics.
|
||||
*/
|
||||
|
||||
class GetAllArticlesController extends Controller {
|
||||
const PATH = '/get-all';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => (Controller::isLoginMandatory()) ? 'user' : 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$topics = Topic::getAll();
|
||||
$topicsArray = [];
|
||||
|
||||
foreach($topics as $topic) {
|
||||
if (Controller::isStaffLogged()) {
|
||||
$topicsArray[] = $topic->toArray();
|
||||
} else if (!$topic->private) {
|
||||
$topicsArray[] = $topic->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
Response::respondSuccess($topicsArray);
|
||||
}
|
||||
}
|
19
dist/api/controllers/staff.php
vendored
Executable file
19
dist/api/controllers/staff.php
vendored
Executable file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
$systemControllerGroup = new ControllerGroup();
|
||||
$systemControllerGroup->setGroupPath('/staff');
|
||||
|
||||
$systemControllerGroup->addController(new GetStaffController);
|
||||
$systemControllerGroup->addController(new AssignStaffController);
|
||||
$systemControllerGroup->addController(new UnAssignStaffController);
|
||||
$systemControllerGroup->addController(new GetTicketStaffController);
|
||||
$systemControllerGroup->addController(new GetNewTicketsStaffController);
|
||||
$systemControllerGroup->addController(new GetAllTicketsStaffController);
|
||||
$systemControllerGroup->addController(new SearchTicketStaffController);
|
||||
$systemControllerGroup->addController(new InviteStaffController);
|
||||
$systemControllerGroup->addController(new GetAllStaffController);
|
||||
$systemControllerGroup->addController(new DeleteStaffController);
|
||||
$systemControllerGroup->addController(new EditStaffController);
|
||||
$systemControllerGroup->addController(new LastEventsStaffController);
|
||||
$systemControllerGroup->addController(new ResendInviteStaffController);
|
||||
|
||||
$systemControllerGroup->finalize();
|
95
dist/api/controllers/staff/assign-ticket.php
vendored
Executable file
95
dist/api/controllers/staff/assign-ticket.php
vendored
Executable file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /staff/assign-ticket Assign ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Assign ticket
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path assigns a ticket to a staff member.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of the ticket to assign.
|
||||
* @apiParam {Number} staffId The id of the staff.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
* @apiUse TICKET_ALREADY_ASSIGNED
|
||||
* @apiUse INVALID_DEPARTMENT
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class AssignStaffController extends Controller {
|
||||
const PATH = '/assign-ticket';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $ticket;
|
||||
private $staffToAssign;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$ticketNumber = Controller::request('ticketNumber');
|
||||
$staffId = Controller::request('staffId');
|
||||
$this->ticket = Ticket::getByTicketNumber($ticketNumber);
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
if($staffId) {
|
||||
$this->staffToAssign = Staff::getDataStore($staffId, 'id');
|
||||
|
||||
if($this->staffToAssign->isNull()) {
|
||||
throw new RequestException(ERRORS::INVALID_STAFF);
|
||||
}
|
||||
|
||||
if(!$this->staffToAssign->sharedDepartmentList->includesId($this->ticket->department->id)) {
|
||||
throw new RequestException(ERRORS::INVALID_DEPARTMENT);
|
||||
}
|
||||
} else {
|
||||
$this->staffToAssign = Controller::getLoggedUser();
|
||||
}
|
||||
|
||||
if($this->ticket->owner) {
|
||||
throw new RequestException(ERRORS::TICKET_ALREADY_ASSIGNED);
|
||||
}
|
||||
|
||||
if(!$user->canManageTicket($this->ticket)) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
} else {
|
||||
$this->staffToAssign->sharedTicketList->add($this->ticket);
|
||||
$this->ticket->owner = $this->staffToAssign;
|
||||
$this->ticket->totalOwners++;
|
||||
$this->ticket->unread = !$this->ticket->isAuthor($this->staffToAssign);
|
||||
$event = Ticketevent::getEvent(Ticketevent::ASSIGN);
|
||||
$event->setProperties(array(
|
||||
'authorStaff' => Controller::getLoggedUser(),
|
||||
'date' => Date::getCurrentDate(),
|
||||
'content' => $this->staffToAssign->name,
|
||||
));
|
||||
$this->ticket->addEvent($event);
|
||||
|
||||
$this->ticket->store();
|
||||
$this->staffToAssign->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
68
dist/api/controllers/staff/delete.php
vendored
Executable file
68
dist/api/controllers/staff/delete.php
vendored
Executable file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/delete Delete staff
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete staff
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path deletes a staff member.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} staffId The id of the staff member.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_STAFF
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
class DeleteStaffController extends Controller {
|
||||
const PATH = '/delete';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'staffId' =>[
|
||||
'validation' => DataValidator::dataStoreId('staff'),
|
||||
'error' => ERRORS::INVALID_STAFF
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$staffId = Controller::request('staffId');
|
||||
$staff = Staff::getDataStore($staffId);
|
||||
|
||||
if($staffId === Controller::getLoggedUser()->id) {
|
||||
throw new RequestException(ERRORS::YOU_CAN_NOT_DELETE_YOURSELF);
|
||||
}
|
||||
|
||||
foreach($staff->sharedTicketList as $ticket) {
|
||||
$ticket->owner = null;
|
||||
$ticket->unreadStaff = true;
|
||||
$ticket->store();
|
||||
}
|
||||
|
||||
foreach($staff->sharedDepartmentList as $department) {
|
||||
$department->owners--;
|
||||
$department->store();
|
||||
}
|
||||
|
||||
RedBean::exec('DELETE FROM log WHERE author_staff_id = ?', [$staffId]);
|
||||
$staff->delete();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
}
|
202
dist/api/controllers/staff/edit.php
vendored
Executable file
202
dist/api/controllers/staff/edit.php
vendored
Executable file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/edit Edit staff
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit staff
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path edits a staff member.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} staffId Id of the staff.
|
||||
* @apiParam {String} departments The name of the departments to change. Optional.
|
||||
* @apiParam {String} email The new email of the staff member. Optional.
|
||||
* @apiParam {String} password The new password of the staff member. Optional.
|
||||
* @apiParam {Number} level The new level of the staff member. Optional.
|
||||
* @apiParam {Boolean} sendEmailOnNewTicket Indicates if it receives an email when a new ticket is created.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_EMAIL
|
||||
* @apiUse INVALID_PASSWORD
|
||||
* @apiUse INVALID_LEVEL
|
||||
* @apiUse INVALID_STAFF
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditStaffController extends Controller {
|
||||
const PATH = '/edit';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $staffInstance;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'email' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::email(), DataValidator::falseVal()),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
],
|
||||
'password' => [
|
||||
'validation' => DataValidator::oneOf(
|
||||
DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_PASSWORD, LengthConfig::MAX_LENGTH_PASSWORD),
|
||||
DataValidator::falseVal()
|
||||
),
|
||||
'error' => ERRORS::INVALID_PASSWORD
|
||||
],
|
||||
'level' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::between(1, 3, true), DataValidator::falseVal()),
|
||||
'error' => ERRORS::INVALID_LEVEL
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$staffId = Controller::request('staffId');
|
||||
|
||||
if(!$staffId) {
|
||||
$this->staffInstance = Controller::getLoggedUser();
|
||||
} else if(Controller::isStaffLogged(3) || ((Controller::isStaffLogged() && Controller::getLoggedUser()->id == $staffId)) ) {
|
||||
$this->staffInstance = Staff::getDataStore($staffId, 'id');
|
||||
|
||||
if($this->staffInstance->isNull()) {
|
||||
throw new RequestException(ERRORS::INVALID_STAFF);
|
||||
}
|
||||
} else {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if(Controller::request('departments')) {
|
||||
$this->updateDepartmentsOwners();
|
||||
}
|
||||
|
||||
$this->editInformation();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
private function editInformation() {
|
||||
|
||||
if(Controller::request('email')) {
|
||||
$newEmail = Controller::request('email');
|
||||
|
||||
$this->verifyEmail($newEmail);
|
||||
|
||||
$this->staffInstance->email = $newEmail;
|
||||
}
|
||||
|
||||
if(Controller::request('password')) {
|
||||
$this->staffInstance->password = Hashing::hashPassword(Controller::request('password'));
|
||||
}
|
||||
|
||||
if(Controller::request('level') && Controller::isStaffLogged(3) && !$this->isModifyingCurrentStaff()) {
|
||||
$this->staffInstance->level = Controller::request('level');
|
||||
}
|
||||
|
||||
if(Controller::request('departments') && Controller::isStaffLogged(3)) {
|
||||
$departmentList = $this->getDepartmentList();
|
||||
$ticketList = $this->staffInstance->sharedTicketList;
|
||||
|
||||
$this->staffInstance->sharedDepartmentList = $departmentList;
|
||||
|
||||
foreach($ticketList as $ticket) {
|
||||
if(!$departmentList->includesId($ticket->department->id)) {
|
||||
if($ticket->isOwner($this->staffInstance) ) {
|
||||
$ticket->owner = null;
|
||||
}
|
||||
|
||||
if(!$ticket->isAuthor($this->staffInstance)) {
|
||||
$this->staffInstance->sharedTicketList->remove($ticket);
|
||||
}
|
||||
|
||||
$ticket->store();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fileUploader = FileUploader::getInstance();
|
||||
$fileUploader->setPermission(FileManager::PERMISSION_PROFILE);
|
||||
|
||||
if($fileUploader = $this->uploadFile(true)) {
|
||||
$this->staffInstance->profilePic = ($fileUploader instanceof FileUploader) ? $fileUploader->getFileName() : null;
|
||||
}
|
||||
|
||||
if(Controller::request('sendEmailOnNewTicket') !== null && Controller::request('sendEmailOnNewTicket') !== '' && $this->isModifyingCurrentStaff()) {
|
||||
$this->staffInstance->sendEmailOnNewTicket = intval(Controller::request('sendEmailOnNewTicket'));
|
||||
}
|
||||
|
||||
$this->staffInstance->store();
|
||||
}
|
||||
|
||||
private function verifyEmail($email){
|
||||
|
||||
$staff = Staff::getDataStore($email,'email');
|
||||
$user = User::getDataStore($email,'email');
|
||||
|
||||
if($user->email == $email){
|
||||
throw new RequestException(ERRORS::INVALID_EMAIL);
|
||||
}
|
||||
|
||||
if($staff->email == $email && $this->staffInstance->email != $email){
|
||||
throw new RequestException(ERRORS::INVALID_EMAIL);
|
||||
}
|
||||
}
|
||||
|
||||
private function getDepartmentList() {
|
||||
$listDepartments = new DataStoreList();
|
||||
$departmentIds = json_decode(Controller::request('departments'));
|
||||
|
||||
foreach($departmentIds as $id) {
|
||||
$department = Department::getDataStore($id);
|
||||
$listDepartments->add($department);
|
||||
}
|
||||
|
||||
return $listDepartments;
|
||||
}
|
||||
|
||||
private function updateDepartmentsOwners() {
|
||||
$list1 = $this->staffInstance->sharedDepartmentList;
|
||||
$list2 = $this->getDepartmentList();
|
||||
|
||||
foreach ($list1 as $department1) {
|
||||
$match = false;
|
||||
|
||||
foreach ($list2 as $department2) {
|
||||
if($department1->id == $department2->id) {
|
||||
$match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$match) {
|
||||
$department1->owners--;
|
||||
$department1->store();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($list2 as $department2) {
|
||||
$match = false;
|
||||
|
||||
foreach ($list1 as $department1) {
|
||||
if($department2->id == $department1->id) {
|
||||
$match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$match) {
|
||||
$department2->owners++;
|
||||
$department2->store();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function isModifyingCurrentStaff() {
|
||||
return !Controller::request('staffId') || Controller::request('staffId') === Controller::getLoggedUser()->id;
|
||||
}
|
||||
}
|
114
dist/api/controllers/staff/get-all-tickets.php
vendored
Executable file
114
dist/api/controllers/staff/get-all-tickets.php
vendored
Executable file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/get-all-tickets Get all tickets according to search
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get all tickets
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @apiSuccess {Object} data Information about a tickets and quantity of pages.
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data.tickets Array of tickets of the current page.
|
||||
* @apiSuccess {Number} data.pages Quantity of pages.
|
||||
*
|
||||
*/
|
||||
|
||||
class GetAllTicketsStaffController extends Controller {
|
||||
const PATH = '/get-all-tickets';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if (Ticket::isTableEmpty()) {
|
||||
Response::respondSuccess([
|
||||
'tickets' => [],
|
||||
'pages' => 0
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
Response::respondSuccess([
|
||||
'tickets' => $this->getTicketList()->toArray(true),
|
||||
'pages' => $this->getTotalPages()
|
||||
]);
|
||||
}
|
||||
|
||||
private function getTicketList() {
|
||||
$page = Controller::request('page');
|
||||
|
||||
$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, [
|
||||
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->getSearchQuery();
|
||||
$query .= $this->getStaffDepartmentsQueryFilter();
|
||||
$query .= $this->getClosedFilter();
|
||||
|
||||
return ceil(Ticket::count($query, [
|
||||
Controller::request('query') . '%',
|
||||
'%' . Controller::request('query') . '%'
|
||||
]) / 10);
|
||||
}
|
||||
|
||||
private function getStaffDepartmentsQueryFilter() {
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
$query = ' (';
|
||||
foreach ($user->sharedDepartmentList as $department) {
|
||||
$query .= 'department_id=' . $department->id . ' OR ';
|
||||
}
|
||||
$query .= 'FALSE) ';
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function getClosedFilter() {
|
||||
$closed = Controller::request('closed')*1;
|
||||
if ($closed) {
|
||||
return '';
|
||||
} else {
|
||||
return " AND (closed = '0')";
|
||||
}
|
||||
}
|
||||
}
|
63
dist/api/controllers/staff/get-all.php
vendored
Executable file
63
dist/api/controllers/staff/get-all.php
vendored
Executable file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/get-all Get all staffs
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get all staffs
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path retrieves information about all the staff member.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[Staff](#api-Data_Structures-ObjectStaff)[]} data Array of staff members.
|
||||
*
|
||||
*/
|
||||
|
||||
class GetAllStaffController extends Controller {
|
||||
const PATH ='/get-all';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function handler() {
|
||||
$staffs = Staff::getAll();
|
||||
$staffArray = [];
|
||||
|
||||
foreach($staffs as $staff) {
|
||||
$assignedTickets = 0;
|
||||
$closedTickets = 0;
|
||||
|
||||
foreach ($staff->sharedTicketList as $ticket) {
|
||||
if(($ticket->closed) && ($ticket->owner_id == $staff->id)) $closedTickets++;
|
||||
if($ticket->owner_id == $staff->id) $assignedTickets++;
|
||||
}
|
||||
|
||||
$staffArray[] = [
|
||||
'id' => $staff->id,
|
||||
'name' => $staff->name,
|
||||
'email' => $staff->email,
|
||||
'profilePic' => $staff->profilePic,
|
||||
'level' => $staff->level,
|
||||
'departments' => $staff->sharedDepartmentList->toArray(),
|
||||
'assignedTickets' => $assignedTickets,
|
||||
'closedTickets' => $closedTickets,
|
||||
'lastLogin' => $staff->lastLogin
|
||||
];
|
||||
}
|
||||
|
||||
Response::respondSuccess($staffArray);
|
||||
|
||||
}
|
||||
}
|
96
dist/api/controllers/staff/get-new-tickets.php
vendored
Executable file
96
dist/api/controllers/staff/get-new-tickets.php
vendored
Executable file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/get-new-tickets Get new tickets
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get new tickets
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path retrieves the new tickets of the departments the staff has assigned.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} page The page number.
|
||||
* @apiParam {Number} departmentId The id of the department searched
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PAGE
|
||||
* @apiUse INVALID_PAGE_SIZE
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
*/
|
||||
|
||||
class GetNewTicketsStaffController extends Controller {
|
||||
const PATH = '/get-new-tickets';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return[
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
],
|
||||
'pageSize' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::intVal()->between(5, 50),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_PAGE_SIZE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
public function handler() {
|
||||
$page = Controller::request('page');
|
||||
$departmentId = Controller::request('departmentId');
|
||||
$pageSize = Controller::request('pageSize') ? Controller::request('pageSize') : 10;
|
||||
|
||||
if (Ticket::isTableEmpty()) {
|
||||
Response::respondSuccess([
|
||||
'tickets' => [],
|
||||
'page' => $page,
|
||||
'pages' => 0
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
$query = ' (';
|
||||
foreach ($user->sharedDepartmentList as $department) {
|
||||
$query .= 'department_id=' . $department->id . ' OR ';
|
||||
}
|
||||
|
||||
$ownerExists = RedBean::exec('SHOW COLUMNS FROM ticket LIKE \'owner_id\'');
|
||||
|
||||
if($ownerExists != 0) {
|
||||
$query .= 'FALSE) AND closed = 0 AND owner_id IS NULL';
|
||||
} else {
|
||||
$query .= 'FALSE) AND closed = 0';
|
||||
}
|
||||
|
||||
if($departmentId) {
|
||||
$query .= ' AND department_id=' . $departmentId;
|
||||
}
|
||||
|
||||
$countTotal = Ticket::count($query);
|
||||
|
||||
$query .= ' ORDER BY unread_staff DESC';
|
||||
$query .= ' LIMIT ' . $pageSize . ' OFFSET ' . ($page-1)*10;
|
||||
|
||||
$ticketList = Ticket::find($query);
|
||||
|
||||
Response::respondSuccess([
|
||||
'tickets' => $ticketList->toArray(true),
|
||||
'page' => $page,
|
||||
'pages' => ceil($countTotal / $pageSize)
|
||||
]);
|
||||
}
|
||||
}
|
85
dist/api/controllers/staff/get-tickets.php
vendored
Executable file
85
dist/api/controllers/staff/get-tickets.php
vendored
Executable file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/get-tickets Get tickets
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get tickets
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path retrieves the tickets assigned to the current staff member.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} page The page number.
|
||||
* @apiParam {bool} closed Include closed tickets in the response.
|
||||
* @apiParam {Number} departmentId The id of the department searched
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PAGE
|
||||
* @apiUse INVALID_PAGE_SIZE
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
*/
|
||||
|
||||
class GetTicketStaffController extends Controller {
|
||||
const PATH = '/get-tickets';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
],
|
||||
'pageSize' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::intVal()->between(5, 50),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_PAGE_SIZE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = Controller::getLoggedUser();
|
||||
$closed = Controller::request('closed');
|
||||
$page = Controller::request('page');
|
||||
$departmentId = Controller::request('departmentId');
|
||||
$pageSize = Controller::request('pageSize') ? Controller::request('pageSize') : 10;
|
||||
$offset = ($page-1)*$pageSize;
|
||||
|
||||
$condition = 'TRUE';
|
||||
$bindings = [];
|
||||
|
||||
if($departmentId) {
|
||||
$condition .= ' AND department_id = ?';
|
||||
$bindings[] = $departmentId;
|
||||
}
|
||||
|
||||
if(!$closed) {
|
||||
$condition .= ' AND closed = ?';
|
||||
$bindings[] = '0';
|
||||
}
|
||||
|
||||
$countTotal = $user->withCondition($condition, $bindings)->countShared('ticket');
|
||||
|
||||
$condition .= ' LIMIT ' . $pageSize . ' OFFSET ?';
|
||||
$bindings[] = $offset;
|
||||
|
||||
$tickets = $user->withCondition($condition, $bindings)->sharedTicketList->toArray(true);
|
||||
|
||||
Response::respondSuccess([
|
||||
'tickets' => $tickets,
|
||||
'page' => $page,
|
||||
'pages' => ceil($countTotal / $pageSize)
|
||||
]);
|
||||
}
|
||||
}
|
74
dist/api/controllers/staff/get.php
vendored
Executable file
74
dist/api/controllers/staff/get.php
vendored
Executable file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /staff/get Get staff
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get staff
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path retrieves information about a staff member.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} staffId The id of the staff member to be searched.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {Object} data Information about a staff member
|
||||
* @apiSuccess {String} data.name Name of the staff member
|
||||
* @apiSuccess {String} data.email Elmail of the staff member
|
||||
* @apiSuccess {String} data.profilePic Profile pic filename of staff member
|
||||
* @apiSuccess {Number} data.level Level of staff member
|
||||
* @apiSuccess {Boolean} data.staff Indicates that it is a staff (always true)
|
||||
* @apiSuccess {[Department](#api-Data_Structures-ObjectDepartment)[]} data.departments Array of departments that has assigned.
|
||||
* @apiSuccess {Boolean} data.sendEmailOnNewTicket Indicates if this member receives a mail when a ticket is created.
|
||||
*
|
||||
*/
|
||||
|
||||
class GetStaffController extends Controller {
|
||||
const PATH = '/get';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
$userId = Controller::request('staffId');
|
||||
$userRow = Staff::getDataStore($userId);
|
||||
|
||||
if($user->level == 3 && !$userRow->isNull()) {
|
||||
$user = $userRow;
|
||||
}
|
||||
|
||||
$parsedDepartmentList = [];
|
||||
$departmentList = $user->sharedDepartmentList;
|
||||
|
||||
foreach($departmentList as $department) {
|
||||
$parsedDepartmentList[] = [
|
||||
'id' => $department->id,
|
||||
'name' => $department->name,
|
||||
'private' => $department->private
|
||||
];
|
||||
}
|
||||
|
||||
Response::respondSuccess([
|
||||
'name' => $user->name,
|
||||
'email' => $user->email,
|
||||
'profilePic' => $user->profilePic,
|
||||
'level' => $user->level,
|
||||
'staff' => true,
|
||||
'departments' => $parsedDepartmentList,
|
||||
'sendEmailOnNewTicket' => $user->sendEmailOnNewTicket
|
||||
]);
|
||||
}
|
||||
}
|
149
dist/api/controllers/staff/invite.php
vendored
Executable file
149
dist/api/controllers/staff/invite.php
vendored
Executable file
@ -0,0 +1,149 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /staff/invite Invite staff
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Invite staff
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path invites a new staff member.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} name The name of the new staff member.
|
||||
* @apiParam {String} email The email of the new staff member.
|
||||
* @apiParam {Number} level The level of the new staff member.
|
||||
* @apiParam {String} profilePic The profile pic of the new staff member.
|
||||
* @apiParam {Number[]} departments The departments that will have assigned the new staff member.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
* @apiUse INVALID_EMAIL
|
||||
* @apiUse INVALID_LEVEL
|
||||
* @apiUse ALREADY_A_STAFF
|
||||
* @apiUse INVALID_DEPARTMENT
|
||||
*
|
||||
* @apiSuccess {Object} data Staff info object
|
||||
* @apiSuccess {Number} data.id Staff id
|
||||
*
|
||||
*/
|
||||
|
||||
class InviteStaffController extends Controller {
|
||||
const PATH = '/invite';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $name;
|
||||
private $email;
|
||||
private $profilePic;
|
||||
private $level;
|
||||
private $departments;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
],
|
||||
'email' => [
|
||||
'validation' => DataValidator::email(),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
],
|
||||
'level' => [
|
||||
'validation' => DataValidator::between(1, 3, true),
|
||||
'error' => ERRORS::INVALID_LEVEL
|
||||
],
|
||||
'departments' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validDepartmentsId(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->storeRequestData();
|
||||
|
||||
$staffRow = Staff::getDataStore($this->email, 'email');
|
||||
|
||||
if(!$staffRow->isNull()) throw new RequestException(ERRORS::ALREADY_A_STAFF);
|
||||
|
||||
$staff = new Staff();
|
||||
$staff->setProperties([
|
||||
'name'=> $this->name,
|
||||
'email' => $this->email,
|
||||
'password'=> Hashing::hashPassword(Hashing::generateRandomToken()),
|
||||
'profilePic' => $this->profilePic,
|
||||
'level' => $this->level,
|
||||
'sharedDepartmentList' => $this->getDepartmentList()
|
||||
]);
|
||||
|
||||
$this->addOwner();
|
||||
|
||||
$this->token = Hashing::generateRandomToken();
|
||||
|
||||
$recoverPassword = new RecoverPassword();
|
||||
$recoverPassword->setProperties(array(
|
||||
'email' => $this->email,
|
||||
'token' => $this->token,
|
||||
'staff' => true
|
||||
));
|
||||
$recoverPassword->store();
|
||||
|
||||
$this->sendInvitationMail();
|
||||
|
||||
Response::respondSuccess([
|
||||
'id' => $staff->store()
|
||||
]);
|
||||
|
||||
Log::createLog('INVITE', $this->name);
|
||||
}
|
||||
|
||||
public function storeRequestData() {
|
||||
$this->name = Controller::request('name');
|
||||
$this->email = Controller::request('email');
|
||||
$this->profilePic = Controller::request('profilePic');
|
||||
$this->level = Controller::request('level');
|
||||
$this->departments = Controller::request('departments');
|
||||
}
|
||||
|
||||
public function getDepartmentList() {
|
||||
$listDepartments = new DataStoreList();
|
||||
$departmentIds = json_decode($this->departments);
|
||||
|
||||
foreach($departmentIds as $id) {
|
||||
$department = Department::getDataStore($id);
|
||||
$listDepartments->add($department);
|
||||
}
|
||||
|
||||
return $listDepartments;
|
||||
}
|
||||
|
||||
public function addOwner() {
|
||||
$departmentIds = json_decode($this->departments);
|
||||
|
||||
foreach($departmentIds as $id) {
|
||||
$departmentRow = Department::getDataStore($id);
|
||||
$departmentRow->owners++;
|
||||
$departmentRow->store();
|
||||
}
|
||||
}
|
||||
|
||||
public function sendInvitationMail() {
|
||||
$mailSender = MailSender::getInstance();
|
||||
|
||||
$mailSender->setTemplate(MailTemplate::USER_INVITE, [
|
||||
'to' => $this->email,
|
||||
'name' => $this->name,
|
||||
'url' => Setting::getSetting('url')->getValue(),
|
||||
'token' => $this->token
|
||||
]);
|
||||
|
||||
$mailSender->send();
|
||||
}
|
||||
}
|
59
dist/api/controllers/staff/last-events.php
vendored
Executable file
59
dist/api/controllers/staff/last-events.php
vendored
Executable file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/last-events Get last events
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get last events
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path retrieves the last events.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} page The page number.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PAGE
|
||||
*
|
||||
* @apiSuccess {[TicketEvent](#api-Data_Structures-ObjectTicketevent)[]} data Array of last events
|
||||
*
|
||||
*/
|
||||
|
||||
class LastEventsStaffController extends Controller {
|
||||
const PATH = '/last-events';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$page = Controller::request('page');
|
||||
|
||||
$user = Controller::getLoggedUser();
|
||||
$query = ' (';
|
||||
foreach ($user->sharedTicketList as $ticket) {
|
||||
$query .= 'ticket_id =' . $ticket->id . ' OR ';
|
||||
}
|
||||
$query = substr($query,0,-3);
|
||||
$query .= ') ORDER BY id desc LIMIT ? OFFSET ?' ;
|
||||
|
||||
if(Ticketevent::count() && !$user->sharedTicketList->isEmpty()) {
|
||||
$eventList = Ticketevent::find($query, [10, 10*($page-1)]);
|
||||
Response::respondSuccess($eventList->toArray());
|
||||
} else {
|
||||
Response::respondSuccess([]);
|
||||
}
|
||||
}
|
||||
}
|
71
dist/api/controllers/staff/resend-invite-staff.php
vendored
Executable file
71
dist/api/controllers/staff/resend-invite-staff.php
vendored
Executable file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /staff/resend-invite-staff resend invite staff
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Resend resend invite staff
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path resend invitation to a staff
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} email The email of the new staff member.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_EMAIL
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class ResendInviteStaffController extends Controller {
|
||||
const PATH = '/resend-invite-staff';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $email;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'email' => [
|
||||
'validation' => DataValidator::email(),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->email = Controller::request('email');
|
||||
|
||||
$staffRow = Staff::getDataStore($this->email, 'email');
|
||||
$recoverPassword = RecoverPassword::getDataStore($this->email, 'email');
|
||||
|
||||
if($staffRow->isNull() || $recoverPassword->isNull() || $recoverPassword->staff != 1) throw new RequestException(ERRORS::INVALID_EMAIL);
|
||||
|
||||
$this->sendInvitationMail($staffRow, $recoverPassword->token);
|
||||
|
||||
Response::respondSuccess();
|
||||
|
||||
Log::createLog('INVITE', $staffRow->name);
|
||||
}
|
||||
|
||||
public function sendInvitationMail($staffRow, $token) {
|
||||
$mailSender = MailSender::getInstance();
|
||||
|
||||
$mailSender->setTemplate(MailTemplate::USER_INVITE, [
|
||||
'to' => $staffRow->email,
|
||||
'name' => $staffRow->name,
|
||||
'url' => Setting::getSetting('url')->getValue(),
|
||||
'token' => $token
|
||||
]);
|
||||
|
||||
$mailSender->send();
|
||||
}
|
||||
}
|
100
dist/api/controllers/staff/search-tickets.php
vendored
Executable file
100
dist/api/controllers/staff/search-tickets.php
vendored
Executable file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /staff/search-tickets Search tickets
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Search tickets
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path search some tickets.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {String} query Query string to search.
|
||||
* @apiParam {Number} page The page number.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_QUERY
|
||||
* @apiUse INVALID_PAGE
|
||||
*
|
||||
* @apiSuccess {Object} data Information about tickets
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)[]} data.tickets Array of tickets found
|
||||
* @apiSuccess {Number} data.pages Number of pages
|
||||
*
|
||||
*/
|
||||
|
||||
class SearchTicketStaffController extends Controller {
|
||||
const PATH = '/search-tickets';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return[
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'query' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_QUERY),
|
||||
'error' => ERRORS::INVALID_QUERY
|
||||
],
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
Response::respondSuccess([
|
||||
'tickets' => $this->getTicketList()->toArray(),
|
||||
'pages' => $this->getTotalPages()
|
||||
]);
|
||||
}
|
||||
|
||||
private function getTicketList() {
|
||||
$query = $this->getSearchQuery();
|
||||
|
||||
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 ";
|
||||
$query .= $this->getStaffDepartmentsQueryFilter();
|
||||
$query .= "ORDER BY CASE WHEN (title LIKE ?) THEN 1 ELSE 2 END ASC LIMIT 10 OFFSET " . (($page-1)*10);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function getTotalPages() {
|
||||
$query = " (title LIKE ? OR title LIKE ?) AND ";
|
||||
$query .= $this->getStaffDepartmentsQueryFilter();
|
||||
|
||||
$ticketQuantity = Ticket::count($query, [
|
||||
Controller::request('query') . '%',
|
||||
'%' . Controller::request('query') . '%'
|
||||
]);
|
||||
|
||||
return ceil($ticketQuantity / 10);
|
||||
}
|
||||
|
||||
private function getStaffDepartmentsQueryFilter() {
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
$query = ' (';
|
||||
foreach ($user->sharedDepartmentList as $department) {
|
||||
$query .= 'department_id=' . $department->id . ' OR ';
|
||||
}
|
||||
$query = substr($query, 0, -3);
|
||||
$query .= ') ';
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
81
dist/api/controllers/staff/un-assign-ticket.php
vendored
Executable file
81
dist/api/controllers/staff/un-assign-ticket.php
vendored
Executable file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /staff/un-assign-ticket Un-assign ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Un-assign ticket
|
||||
*
|
||||
* @apiGroup Staff
|
||||
*
|
||||
* @apiDescription This path un-assigns a ticket to the current staff member.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} ticketNumber Ticket number to un-assign.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class UnAssignStaffController extends Controller {
|
||||
const PATH = '/un-assign-ticket';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $user;
|
||||
|
||||
public function __construct($user=null) {
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$ticketNumber = Controller::request('ticketNumber');
|
||||
$user = ($this->user? $this->user : Controller::getLoggedUser());
|
||||
$ticket = Ticket::getByTicketNumber($ticketNumber);
|
||||
$owner = $ticket->owner;
|
||||
|
||||
if(!$user->canManageTicket($ticket)) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if($owner) {
|
||||
if(!$ticket->isAuthor($owner)) {
|
||||
$owner->sharedTicketList->remove($ticket);
|
||||
$owner->store();
|
||||
}
|
||||
|
||||
$ticket->owner = null;
|
||||
$ticket->unread = !$ticket->isAuthor($user);
|
||||
|
||||
$event = Ticketevent::getEvent(Ticketevent::UN_ASSIGN);
|
||||
$event->setProperties(array(
|
||||
'authorStaff' => $user,
|
||||
'date' => Date::getCurrentDate(),
|
||||
'content' => $owner->name
|
||||
));
|
||||
|
||||
$ticket->addEvent($event);
|
||||
$ticket->store();
|
||||
Response::respondSuccess();
|
||||
} else {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
}
|
||||
}
|
39
dist/api/controllers/system.php
vendored
Executable file
39
dist/api/controllers/system.php
vendored
Executable file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
$systemControllerGroup = new ControllerGroup();
|
||||
$systemControllerGroup->setGroupPath('/system');
|
||||
|
||||
$systemControllerGroup->addController(new CheckRequirementsController);
|
||||
$systemControllerGroup->addController(new InitDatabaseController);
|
||||
$systemControllerGroup->addController(new InitSettingsController);
|
||||
$systemControllerGroup->addController(new InitAdminController);
|
||||
$systemControllerGroup->addController(new InstallationDoneController);
|
||||
$systemControllerGroup->addController(new GetSettingsController);
|
||||
$systemControllerGroup->addController(new EditSettingsController);
|
||||
$systemControllerGroup->addController(new AddDepartmentController);
|
||||
$systemControllerGroup->addController(new EditDepartmentController);
|
||||
$systemControllerGroup->addController(new DeleteDepartmentController);
|
||||
$systemControllerGroup->addController(new GetLogsController);
|
||||
$systemControllerGroup->addController(new GetMailTemplateListController);
|
||||
$systemControllerGroup->addController(new GetMailTemplateController);
|
||||
$systemControllerGroup->addController(new EditMailTemplateController);
|
||||
$systemControllerGroup->addController(new RecoverMailTemplateController);
|
||||
$systemControllerGroup->addController(new DisableRegistrationController);
|
||||
$systemControllerGroup->addController(new EnableRegistrationController);
|
||||
$systemControllerGroup->addController(new AddAPIKeyController);
|
||||
$systemControllerGroup->addController(new DeleteAPIKeyController);
|
||||
$systemControllerGroup->addController(new GetAPIKeysController);
|
||||
$systemControllerGroup->addController(new DeleteAllUsersController);
|
||||
$systemControllerGroup->addController(new BackupDatabaseController);
|
||||
$systemControllerGroup->addController(new DownloadController);
|
||||
$systemControllerGroup->addController(new CSVImportController);
|
||||
$systemControllerGroup->addController(new EnableMandatoryLoginController);
|
||||
$systemControllerGroup->addController(new DisableMandatoryLoginController);
|
||||
$systemControllerGroup->addController(new TestSMTPController);
|
||||
$systemControllerGroup->addController(new TestIMAPController);
|
||||
$systemControllerGroup->addController(new EmailPollingController);
|
||||
$systemControllerGroup->addController(new AddCustomFieldController);
|
||||
$systemControllerGroup->addController(new DeleteCustomFieldController);
|
||||
$systemControllerGroup->addController(new GetCustomFieldsController);
|
||||
$systemControllerGroup->addController(new GetStatsController);
|
||||
|
||||
$systemControllerGroup->finalize();
|
74
dist/api/controllers/system/add-api-key.php
vendored
Executable file
74
dist/api/controllers/system/add-api-key.php
vendored
Executable file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/add-api-key Add APIKey
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Add APIKey
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path creates a new APIKey.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} name Name of the new APIKey.
|
||||
* @apiParam {Boolean} canCreateUsers canCreateUsers determinates if the apikey has the permission to create users
|
||||
* @apiParam {Boolean} canCreateTickets canCreateTickets determinates if the apikey has the permission to create tickets
|
||||
* @apiParam {Boolean} canCheckTickets canCheckTickets determinates if the apikey has the permission to check tickets
|
||||
* @apiParam {Boolean} shouldReturnTicketNumber shouldReturnTicketNumber determinates if the apikey has the permission of returning ticket number after ticket creation
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
* @apiUse NAME_ALREADY_USED
|
||||
*
|
||||
* @apiSuccess {String} data Token of the APIKey.
|
||||
*
|
||||
*/
|
||||
|
||||
class AddAPIKeyController extends Controller {
|
||||
const PATH = '/add-api-key';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME)->alnum(),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$apiInstance = new APIKey();
|
||||
|
||||
$name = Controller::request('name');
|
||||
$canCreateUsers = (bool)Controller::request('canCreateUsers');
|
||||
$canCreateTickets = (bool)Controller::request('canCreateTickets');
|
||||
$canCheckTickets = (bool)Controller::request('canCheckTickets');
|
||||
$shouldReturnTicketNumber = (bool)Controller::request('shouldReturnTicketNumber');
|
||||
$keyInstance = APIKey::getDataStore($name, 'name');
|
||||
|
||||
if($keyInstance->isNull()){
|
||||
$token = Hashing::generateRandomToken();
|
||||
|
||||
$apiInstance->setProperties([
|
||||
'name' => $name,
|
||||
'token' => $token,
|
||||
'canCreateUsers' => $canCreateUsers,
|
||||
'canCreateTickets' => $canCreateTickets,
|
||||
'canCheckTickets' => $canCheckTickets,
|
||||
'shouldReturnTicketNumber' => $shouldReturnTicketNumber
|
||||
]);
|
||||
|
||||
$apiInstance->store();
|
||||
Response::respondSuccess($token);
|
||||
} else {
|
||||
throw new RequestException(ERRORS::NAME_ALREADY_USED);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
105
dist/api/controllers/system/add-custom-field.php
vendored
Executable file
105
dist/api/controllers/system/add-custom-field.php
vendored
Executable file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /system/add-custom-field Add a custom field
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Add Custom field
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path creates a Custom field.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {Number} name Name of the custom field.
|
||||
* @apiParam {String} type One of 'text' and 'select'.
|
||||
* @apiParam {String} options JSON array of strings with the option names.
|
||||
* @apiParam {String} description Description of the custom field.
|
||||
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
* @apiUse INVALID_CUSTOM_FIELD_TYPE
|
||||
* @apiUse INVALID_CUSTOM_FIELD_OPTIONS
|
||||
* @apiUse CUSTOM_FIELD_ALREADY_EXISTS
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class AddCustomFieldController extends Controller {
|
||||
const PATH = '/add-custom-field';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
],
|
||||
'description' => [
|
||||
'validation' => DataValidator::length(LengthConfig::MIN_LENGTH_DESCRIPTION, LengthConfig::MAX_LENGTH_DESCRIPTION),
|
||||
'error' => ERRORS::INVALID_DESCRIPTION
|
||||
],
|
||||
'type' => [
|
||||
'validation' => DataValidator::oneOf(
|
||||
DataValidator::equals('text'),
|
||||
DataValidator::equals('select')
|
||||
),
|
||||
'error' => ERRORS::INVALID_CUSTOM_FIELD_TYPE
|
||||
],
|
||||
'options' => [
|
||||
'validation' => DataValidator::oneOf(
|
||||
DataValidator::ValidOptions(),
|
||||
DataValidator::nullType()
|
||||
),
|
||||
'error' => ERRORS::INVALID_CUSTOM_FIELD_OPTIONS
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$name = Controller::request('name', true);
|
||||
$type = Controller::request('type');
|
||||
$description = Controller::request('description', true);
|
||||
$options = Controller::request('options');
|
||||
|
||||
if(!Customfield::getDataStore($name, 'name')->isNull()) {
|
||||
throw new Exception(ERRORS::CUSTOM_FIELD_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$customField = new Customfield();
|
||||
$customField->setProperties([
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'description' => $description,
|
||||
'ownCustomfieldoptionList' => $this->getOptionList($options)
|
||||
]);
|
||||
|
||||
$customField->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
public function getOptionList($optionNames) {
|
||||
$options = new DataStoreList();
|
||||
if(!$optionNames) return $options;
|
||||
|
||||
$optionNames = json_decode($optionNames);
|
||||
|
||||
foreach($optionNames as $optionName) {
|
||||
$option = new Customfieldoption();
|
||||
$option->setProperties([
|
||||
'name' => $optionName,
|
||||
]);
|
||||
$options->add($option);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
62
dist/api/controllers/system/add-department.php
vendored
Executable file
62
dist/api/controllers/system/add-department.php
vendored
Executable file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
DataValidator::with('CustomValidations', true);
|
||||
/**
|
||||
* @api {post} /system/add-department Add department
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Add department
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path create a new department.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} name Name of the new department.
|
||||
* @apiParam {Boolean} private Indicates if the deparment is not shown to users.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class AddDepartmentController extends Controller {
|
||||
const PATH = '/add-department';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::AllOf(
|
||||
DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
DataValidator::ValidDepartmentName()
|
||||
),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$name = Controller::request('name', true);
|
||||
$private = Controller::request('private');
|
||||
|
||||
$departmentInstance = new Department();
|
||||
|
||||
$departmentInstance->setProperties([
|
||||
'name' => $name ,
|
||||
'private' => $private ? 1 : 0
|
||||
]);
|
||||
$departmentInstance->store();
|
||||
|
||||
Log::createLog('ADD_DEPARTMENT', $name);
|
||||
|
||||
Response::respondSuccess();
|
||||
|
||||
}
|
||||
}
|
44
dist/api/controllers/system/backup-database.php
vendored
Executable file
44
dist/api/controllers/system/backup-database.php
vendored
Executable file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
use Ifsnop\Mysqldump as IMysqldump;
|
||||
|
||||
/**
|
||||
* @api {post} /system/backup-database Backup database
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Backup database
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path does a backup of the database.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {File} file File of the backup
|
||||
*
|
||||
*/
|
||||
|
||||
class BackupDatabaseController extends Controller {
|
||||
const PATH = '/backup-database';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$fileDownloader = FileDownloader::getInstance();
|
||||
$fileDownloader->setFileName('backup.sql');
|
||||
|
||||
$mysqlDump = new IMysqldump\Mysqldump('mysql:host='. MYSQL_HOST . ';port=' . MYSQL_PORT . ';dbname=' . MYSQL_DATABASE , MYSQL_USER, MYSQL_PASSWORD);
|
||||
$mysqlDump->start($fileDownloader->getFullFilePath());
|
||||
|
||||
if($fileDownloader->download()) {
|
||||
$fileDownloader->eraseFile();
|
||||
}
|
||||
}
|
||||
}
|
69
dist/api/controllers/system/check-requirements.php
vendored
Executable file
69
dist/api/controllers/system/check-requirements.php
vendored
Executable file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api {post} /system/check-requirements Checks requirements
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Check requirements
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path checks and retrieves the current requirements for the installation.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiSuccess {Object} data
|
||||
*
|
||||
*/
|
||||
|
||||
class CheckRequirementsController extends Controller {
|
||||
const PATH = '/check-requirements';
|
||||
const METHOD = 'POST';
|
||||
|
||||
const requiredPHPVersion = '5.6';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if(InstallationDoneController::isInstallationDone()) {
|
||||
throw new RequestException(ERRORS::INIT_SETTINGS_DONE);
|
||||
}
|
||||
|
||||
Response::respondSuccess([
|
||||
'phpVersion' => [
|
||||
'name' => 'PHP Version',
|
||||
'value' => phpversion(),
|
||||
'ok' => $this->checkVersion()
|
||||
],
|
||||
'PDO' => [
|
||||
'name' => 'PDO Module',
|
||||
'value' => class_exists('PDO') ? 'Available' : 'Not available',
|
||||
'ok' => class_exists('PDO')
|
||||
],
|
||||
'configFile' => [
|
||||
'name' => 'File: /api/config.php',
|
||||
'value' => is_writable('config.php') ? 'Writable' : 'Not writable',
|
||||
'ok' => is_writable('config.php')
|
||||
],
|
||||
'files' => [
|
||||
'name' => 'Folder: /api/files',
|
||||
'value' => is_writable('files') ? 'Writable' : 'Not writable',
|
||||
'ok' => is_writable('files')
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
private function checkVersion() {
|
||||
$requiredVersion = explode('.', CheckRequirementsController::requiredPHPVersion);
|
||||
$currentVersion = explode('.', phpversion());
|
||||
|
||||
if($currentVersion[0] > $requiredVersion[0]) return true;
|
||||
else if($currentVersion[0] < $requiredVersion[0]) return false;
|
||||
else return $currentVersion[1] >= $requiredVersion[1];
|
||||
}
|
||||
}
|
90
dist/api/controllers/system/csv-import.php
vendored
Executable file
90
dist/api/controllers/system/csv-import.php
vendored
Executable file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /system/csv-import CSV import
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName CSV import
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path receives a csv file with a list of users to signup.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} file A csv file with this content format: email, password, name.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PASSWORD
|
||||
* @apiUse INVALID_FILE
|
||||
*
|
||||
* @apiSuccess {String[]} data Array of errors found
|
||||
*
|
||||
*/
|
||||
|
||||
class CSVImportController extends Controller {
|
||||
const PATH = '/csv-import';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [],
|
||||
'password' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_PASSWORD, LengthConfig::MAX_LENGTH_PASSWORD),
|
||||
'error' => ERRORS::INVALID_PASSWORD
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$password = Controller::request('password');
|
||||
|
||||
if(!Hashing::verifyPassword($password, Controller::getLoggedUser()->password)) {
|
||||
throw new RequestException(ERRORS::INVALID_PASSWORD);
|
||||
}
|
||||
|
||||
$fileUploader = $this->uploadFile(true);
|
||||
|
||||
if(!$fileUploader instanceof FileUploader) {
|
||||
throw new RequestException(ERRORS::INVALID_FILE);
|
||||
}
|
||||
|
||||
$fileDownloader = FileDownloader::getInstance();
|
||||
$fileDownloader->setFileName($fileUploader->getFileName());
|
||||
$file = $fileDownloader->fopen();
|
||||
|
||||
$errors = [];
|
||||
|
||||
while($file && ($user = fgetcsv($file)) != false) {
|
||||
Controller::setDataRequester(function ($key) use ($user) {
|
||||
switch ($key) {
|
||||
case 'email':
|
||||
return $user[0];
|
||||
case 'password':
|
||||
return $user[1];
|
||||
case 'name':
|
||||
return $user[2];
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
$signupController = new SignUpController(true);
|
||||
|
||||
try {
|
||||
$signupController->validate();
|
||||
$signupController->handler();
|
||||
} catch (\Exception $exception) {
|
||||
$errors[] = $exception->getMessage() . ' in email ' . $user[0];
|
||||
}
|
||||
}
|
||||
|
||||
fclose($file);
|
||||
|
||||
unlink($fileUploader->getFullFilePath());
|
||||
Response::respondSuccess($errors);
|
||||
}
|
||||
}
|
54
dist/api/controllers/system/delete-all-users.php
vendored
Executable file
54
dist/api/controllers/system/delete-all-users.php
vendored
Executable file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
/**
|
||||
* @api {post} /system/delete-all-users Delete all users
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete all users
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path deletes all users in database.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} password The password of the current staff.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PASSWORD
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteAllUsersController extends Controller {
|
||||
const PATH = '/delete-all-users';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$password = Controller::request('password');
|
||||
|
||||
if(!Hashing::verifyPassword($password, Controller::getLoggedUser()->password)) {
|
||||
throw new RequestException(ERRORS::INVALID_PASSWORD);
|
||||
return;
|
||||
}
|
||||
|
||||
Redbean::exec('SET FOREIGN_KEY_CHECKS = 0;');
|
||||
RedBean::wipe(SessionCookie::TABLE);
|
||||
RedBean::wipe(User::TABLE);
|
||||
RedBean::wipe(Ticket::TABLE);
|
||||
RedBean::wipe(Ticketevent::TABLE);
|
||||
RedBean::wipe('ticket_user');
|
||||
Redbean::exec('SET FOREIGN_KEY_CHECKS = 1;');
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
54
dist/api/controllers/system/delete-api-key.php
vendored
Executable file
54
dist/api/controllers/system/delete-api-key.php
vendored
Executable file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/delete-api-key Delete APIKey
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete APIKey
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path deletes an APIKey.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} name Name of the APIKey to delete.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteAPIKeyController extends Controller {
|
||||
const PATH = '/delete-api-key';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$name = Controller::request('name');
|
||||
|
||||
$keyInstance = APIKey::getDataStore($name, 'name');
|
||||
|
||||
if($keyInstance->isNull()) {
|
||||
throw new RequestException(ERRORS::INVALID_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
$keyInstance->delete();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
60
dist/api/controllers/system/delete-custom-field.php
vendored
Executable file
60
dist/api/controllers/system/delete-custom-field.php
vendored
Executable file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/delete-custom-field Delete custom field
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete a custom field
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path deletes a custom field and all its uses.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {Number} id Id of the custom field to delete.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_CUSTOM_FIELD
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteCustomFieldController extends Controller {
|
||||
const PATH = '/delete-custom-field';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'id' => [
|
||||
'validation' => DataValidator::dataStoreId('customfield'),
|
||||
'error' => ERRORS::INVALID_CUSTOM_FIELD,
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$customField = Customfield::getDataStore(Controller::request('id'));
|
||||
|
||||
foreach(User::getAll() as $user) {
|
||||
$customFieldValueList = $user->xownCustomfieldvalueList ? $user->xownCustomfieldvalueList : [];
|
||||
|
||||
foreach($customFieldValueList as $customFieldValue) {
|
||||
if($customFieldValue->customfield->id == $customField->id) {
|
||||
$user->xownCustomfieldvalueList->remove($customFieldValue);
|
||||
}
|
||||
}
|
||||
|
||||
$user->store();
|
||||
}
|
||||
|
||||
$customField->delete();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
119
dist/api/controllers/system/delete-department.php
vendored
Executable file
119
dist/api/controllers/system/delete-department.php
vendored
Executable file
@ -0,0 +1,119 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /system/delete-department Delete department
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete department
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path deletes a department.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} departmentId Id of the department to be deleted.
|
||||
* @apiParam {Number} transferDepartmentId Id of the department where the tickets will be transfer to.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_DEPARTMENT
|
||||
* @apiUse SAME_DEPARTMENT
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteDepartmentController extends Controller {
|
||||
const PATH = '/delete-department';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $departmentId;
|
||||
private $transferDepartmentId;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'departmentId' => [
|
||||
'validation' => DataValidator::dataStoreId('department'),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT
|
||||
],
|
||||
'transferDepartmentId' => [
|
||||
'validation' => DataValidator::dataStoreId('department'),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
|
||||
$this->departmentId = Controller::request('departmentId');
|
||||
$this->transferDepartmentId = Controller::request('transferDepartmentId');
|
||||
|
||||
$this->checkDepartmentIdDefault();
|
||||
|
||||
if ($this->departmentId === $this->transferDepartmentId) {
|
||||
throw new RequestException(ERRORS::SAME_DEPARTMENT);
|
||||
}
|
||||
|
||||
$departmentToTransfer = Department::getDataStore($this->transferDepartmentId);
|
||||
$departmentInstance = Department::getDataStore($this->departmentId);
|
||||
|
||||
if($departmentToTransfer->private && Ticket::count(' author_id IS NOT NULL AND department_id = ? ', [$departmentInstance->id])) {
|
||||
throw new RequestException(ERRORS::DEPARTMENT_PRIVATE_TICKETS);
|
||||
}
|
||||
|
||||
$this->transferDepartmentTickets();
|
||||
$departmentInstance->delete();
|
||||
|
||||
Log::createLog('DELETE_DEPARTMENT', $departmentInstance->name);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
public function transferDepartmentTickets() {
|
||||
$tickets = Ticket::find('department_id = ?', [$this->departmentId]);
|
||||
$newDepartment = Department::getDataStore($this->transferDepartmentId);
|
||||
|
||||
foreach($tickets as $ticket) {
|
||||
$staffOwner = $ticket->owner;
|
||||
|
||||
if($staffOwner) {
|
||||
$hasDepartment = false;
|
||||
|
||||
foreach($staffOwner->sharedDepartmentList as $department) {
|
||||
if($department->id === $newDepartment->id) {
|
||||
$hasDepartment = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$hasDepartment) {
|
||||
$staffOwner->sharedTicketList->remove($ticket);
|
||||
$staffOwner->store();
|
||||
|
||||
$ticket->owner = null;
|
||||
$ticket->unread = true;
|
||||
|
||||
$event = Ticketevent::getEvent(Ticketevent::UN_ASSIGN);
|
||||
$event->setProperties(array(
|
||||
'authorStaff' => $staffOwner,
|
||||
'date' => Date::getCurrentDate()
|
||||
));
|
||||
|
||||
$ticket->addEvent($event);
|
||||
}
|
||||
}
|
||||
|
||||
$ticket->department = $newDepartment;
|
||||
$ticket->store();
|
||||
}
|
||||
}
|
||||
public function checkDepartmentIdDefault() {
|
||||
$defaultDepartment = Setting::getSetting('default-department-id');
|
||||
|
||||
if ($defaultDepartment && $this->departmentId == $defaultDepartment->value) throw new Exception(ERRORS::CAN_NOT_DELETE_DEFAULT_DEPARTMENT);
|
||||
}
|
||||
}
|
54
dist/api/controllers/system/disable-mandatory-login.php
vendored
Executable file
54
dist/api/controllers/system/disable-mandatory-login.php
vendored
Executable file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api {post} /system/disable-mandatory-login Disable mandatory Login
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Disable Mandatory Login
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path disables the mandatory Login.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} password The password of the current staff.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PASSWORD
|
||||
* @apiUse REGISTRATION_IS_DESACTIVATED
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DisableMandatoryLoginController extends Controller {
|
||||
const PATH = '/disable-mandatory-login';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$password = Controller::request('password');
|
||||
|
||||
if(!Setting::getSetting('registration')->getValue()) {
|
||||
throw new Exception(ERRORS::REGISTRATION_IS_DESACTIVATED);
|
||||
}
|
||||
|
||||
if(!Hashing::verifyPassword($password, Controller::getLoggedUser()->password)) {
|
||||
throw new RequestException(ERRORS::INVALID_PASSWORD);
|
||||
}
|
||||
|
||||
$mandatoryLoginRow = Setting::getSetting('mandatory-login');
|
||||
|
||||
$mandatoryLoginRow->value = 0;
|
||||
$mandatoryLoginRow->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
53
dist/api/controllers/system/disable-registration.php
vendored
Executable file
53
dist/api/controllers/system/disable-registration.php
vendored
Executable file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api {post} /system/disable-registration Disable registration
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Disable registration
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path disables the registration.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} password The password of the current staff.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PASSWORD
|
||||
* @apiUse MANDATORY_LOGIN_IS_DESACTIVATED
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DisableRegistrationController extends Controller {
|
||||
const PATH = '/disable-registration';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$password = Controller::request('password');
|
||||
|
||||
if(!Hashing::verifyPassword($password, Controller::getLoggedUser()->password)) {
|
||||
throw new RequestException(ERRORS::INVALID_PASSWORD);
|
||||
return;
|
||||
}
|
||||
if(!Setting::getSetting('mandatory-login')->getValue()) {
|
||||
throw new Exception(ERRORS::MANDATORY_LOGIN_IS_DESACTIVATED);
|
||||
}
|
||||
$registrationRow = Setting::getSetting('registration');
|
||||
|
||||
$registrationRow->value = false;
|
||||
$registrationRow->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
94
dist/api/controllers/system/download.php
vendored
Executable file
94
dist/api/controllers/system/download.php
vendored
Executable file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
use Ifsnop\Mysqldump as IMysqldump;
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {get} /system/download Download file
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Download file
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path downloads a file.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {String} file The filename to be downloaded.
|
||||
*
|
||||
* @apiError 403 You have no permission to access the file.
|
||||
*
|
||||
* @apiSuccess {Object} file File content
|
||||
*
|
||||
*/
|
||||
|
||||
class DownloadController extends Controller {
|
||||
const PATH = '/download';
|
||||
const METHOD = 'GET';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => [
|
||||
'file' => [
|
||||
'validation' => DataValidator::alnum('_.-')->noWhitespace(),
|
||||
'error' => ERRORS::INVALID_FILE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$fileName = Controller::request('file');
|
||||
$isStaffProfilePic = !Staff::getDataStore($fileName, 'profilePic')->isNull();
|
||||
|
||||
$fileDownloader = FileDownloader::getInstance();
|
||||
$fileDownloader->setFileName($fileName);
|
||||
|
||||
$session = Session::getInstance();
|
||||
|
||||
if(!$session->isStaffLogged()) {
|
||||
switch($fileDownloader->getFilePermission()) {
|
||||
case FileManager::PERMISSION_TICKET:
|
||||
$ticketNumber = $fileDownloader->getTicketNumber();
|
||||
$ticket = Ticket::getByTicketNumber($ticketNumber);
|
||||
if($this->isNotAuthor($ticket, Controller::getLoggedUser())) {
|
||||
return Response::respond403();
|
||||
}
|
||||
break;
|
||||
case FileManager::PERMISSION_ARTICLE:
|
||||
if(!$session->sessionExists()) {
|
||||
return Response::respond403();
|
||||
}
|
||||
break;
|
||||
case FileManager::PERMISSION_PROFILE:
|
||||
break;
|
||||
default:
|
||||
return Response::respond403();
|
||||
}
|
||||
}
|
||||
|
||||
$fileDownloader->download();
|
||||
exit();
|
||||
}
|
||||
|
||||
private function isNotAuthor($ticket, $loggedUser) {
|
||||
$session = Session::getInstance();
|
||||
|
||||
if($session->getTicketNumber()) {
|
||||
return $session->getTicketNumber() !== $ticket->ticketNumber;
|
||||
} else {
|
||||
return $ticket->author->id !== $loggedUser->id || ($loggedUser instanceof Staff) !== $ticket->authorToArray()['staff'];
|
||||
}
|
||||
}
|
||||
|
||||
private function isNotDepartmentOwner($ticket, $loggedUser) {
|
||||
$session = Session::getInstance();
|
||||
|
||||
if($session->getTicketNumber()) {
|
||||
return $session->getTicketNumber() !== $ticket->ticketNumber;
|
||||
} else {
|
||||
return !($loggedUser->level >= 1) || !$loggedUser->sharedDepartmentList->includesId($ticket->department->id);
|
||||
}
|
||||
}
|
||||
}
|
79
dist/api/controllers/system/edit-department.php
vendored
Executable file
79
dist/api/controllers/system/edit-department.php
vendored
Executable file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /system/edit-department Edit department
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit department
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path edits a department's name.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} name The new name of the department.
|
||||
* @apiParam {Number} departmentId The Id of the department.
|
||||
* @apiParam {Boolean} private Indicates if the department is shown to users;
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
* @apiUse INVALID_DEPARTMENT
|
||||
* @apiUse NAME_ALREADY_USED
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditDepartmentController extends Controller {
|
||||
const PATH = '/edit-department';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'departmentId' => [
|
||||
'validation' => DataValidator::dataStoreId('department'),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT
|
||||
],
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$newName = Controller::request('name');
|
||||
$departmentId = Controller::request('departmentId');
|
||||
$private = Controller::request('private');
|
||||
|
||||
$departmentInstance = Department::getDataStore($departmentId);
|
||||
$createdDepartment = Department::getDataStore($newName, 'name');
|
||||
|
||||
if(!$createdDepartment->isNull() && $createdDepartment->name !== $departmentInstance->name){
|
||||
throw new RequestException(ERRORS::NAME_ALREADY_USED);
|
||||
}
|
||||
|
||||
if($private && $departmentId == Setting::getSetting('default-department-id')->getValue()){
|
||||
throw new RequestException(ERRORS::DEFAULT_DEPARTMENT_CAN_NOT_BE_PRIVATE);
|
||||
}
|
||||
|
||||
if($private && Ticket::count(' author_id IS NOT NULL AND department_id = ? ', [$departmentId])) {
|
||||
throw new RequestException(ERRORS::DEPARTMENT_PRIVATE_TICKETS);
|
||||
}
|
||||
|
||||
if($newName) $departmentInstance->name = $newName;
|
||||
$departmentInstance->private = $private ? 1 : 0;
|
||||
$departmentInstance->store();
|
||||
|
||||
Log::createLog('EDIT_DEPARTMENT', $departmentInstance->name);
|
||||
|
||||
Response::respondSuccess();
|
||||
|
||||
}
|
||||
}
|
143
dist/api/controllers/system/edit-mail-template.php
vendored
Executable file
143
dist/api/controllers/system/edit-mail-template.php
vendored
Executable file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/edit-mail-template Edit mail template
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit mail template
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path edits a mail template.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @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} 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_TEXT_1
|
||||
* @apiUse INVALID_TEXT_2
|
||||
* @apiUse INVALID_TEXT_3
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditMailTemplateController extends Controller {
|
||||
const PATH = '/edit-mail-template';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $language;
|
||||
private $templateType;
|
||||
private $subject;
|
||||
private $texts;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'template' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TEMPLATE),
|
||||
'error' => ERRORS::INVALID_TEMPLATE
|
||||
],
|
||||
'language' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(Language::getSupportedLanguages()), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_LANGUAGE
|
||||
],
|
||||
'subject' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_SUBJECT),
|
||||
'error' => ERRORS::INVALID_SUBJECT
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$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]);
|
||||
|
||||
if($mailTemplate->isNull()) {
|
||||
throw new RequestException(ERRORS::INVALID_TEMPLATE);
|
||||
}
|
||||
|
||||
$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(array_key_exists(1, $originalText) && !$this->includes(
|
||||
$this->getReplacementStrings($originalText[1]),
|
||||
$this->getReplacementStrings($this->texts[0])
|
||||
)) {
|
||||
throw new RequestException(ERRORS::INVALID_TEXT_1);
|
||||
}
|
||||
|
||||
if(array_key_exists(2, $originalText) && !$this->includes(
|
||||
$this->getReplacementStrings($originalText[2]),
|
||||
$this->getReplacementStrings($this->texts[1])
|
||||
)) {
|
||||
throw new RequestException(ERRORS::INVALID_TEXT_2);
|
||||
}
|
||||
|
||||
if(array_key_exists(3, $originalText) && !$this->includes(
|
||||
$this->getReplacementStrings($originalText[3]),
|
||||
$this->getReplacementStrings($this->texts[2])
|
||||
)) {
|
||||
throw new RequestException(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; $i<strlen($string)-1; $i++) {
|
||||
if($string[$i] == '{' && $string[$i+1] == '{') {
|
||||
$replacement = "";
|
||||
$i += 2;
|
||||
for(; $i<strlen($string)-1;$i++) {
|
||||
if($string[$i] == '}' && $string[$i+1] == '}') break;
|
||||
$replacement .= $string[$i];
|
||||
}
|
||||
|
||||
$replacements[] = $replacement;
|
||||
}
|
||||
}
|
||||
|
||||
return $replacements;
|
||||
}
|
||||
}
|
122
dist/api/controllers/system/edit-settings.php
vendored
Executable file
122
dist/api/controllers/system/edit-settings.php
vendored
Executable file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /system/edit-settings Edit settings
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit settings
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path edit the settings of the system.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} allowedLanguages The list of languages allowed.
|
||||
* @apiParam {String} supportedLanguages The list of languages supported.
|
||||
* @apiParam {Setting} setting A setting can be any of the following: language, recaptcha-public, recaptcha-private, server-email, smtp-host, smtp-port, smtp-user, smtp-pass, maintenance-mode, layout, allow-attachments, max-size, title, url.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditSettingsController extends Controller {
|
||||
const PATH = '/edit-settings';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'default-department-id' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::dataStoreId('department'),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_DEFAULT_DEPARTMENT
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$settings = [
|
||||
'language',
|
||||
'recaptcha-public',
|
||||
'recaptcha-private',
|
||||
'server-email',
|
||||
'imap-host',
|
||||
'imap-user',
|
||||
'imap-pass',
|
||||
'imap-token',
|
||||
'smtp-host',
|
||||
'smtp-user',
|
||||
'smtp-pass',
|
||||
'maintenance-mode',
|
||||
'layout',
|
||||
'allow-attachments',
|
||||
'max-size',
|
||||
'title',
|
||||
'url',
|
||||
'mail-template-header-image',
|
||||
'default-is-locked',
|
||||
'default-department-id'
|
||||
];
|
||||
$this->checkDefaultDepartmentValid();
|
||||
|
||||
foreach($settings as $setting) {
|
||||
if(Controller::request($setting)!==null) {
|
||||
$settingInstance = Setting::getSetting($setting);
|
||||
$settingInstance->value = Controller::request($setting);
|
||||
$settingInstance->store();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(Controller::request('allowedLanguages') || Controller::request('supportedLanguages')) {
|
||||
$this->handleLanguages();
|
||||
}
|
||||
|
||||
Log::createLog('EDIT_SETTINGS', null);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
public function handleLanguages() {
|
||||
$allowed = json_decode(Controller::request('allowedLanguages'));
|
||||
$supported = json_decode(Controller::request('supportedLanguages'));
|
||||
|
||||
if (array_diff($supported, $allowed)) {
|
||||
throw new RequestException(ERRORS::INVALID_SUPPORTED_LANGUAGES);
|
||||
}
|
||||
|
||||
foreach(Language::LANGUAGES as $languageCode) {
|
||||
$language = Language::getDataStore($languageCode, 'code');
|
||||
|
||||
$language->allowed = in_array($languageCode, $allowed);
|
||||
$language->supported = in_array($languageCode, $supported);
|
||||
|
||||
$language->store();
|
||||
}
|
||||
}
|
||||
|
||||
public function checkDefaultDepartmentValid() {
|
||||
$departmentId = Controller::request('default-department-id');
|
||||
|
||||
if($departmentId){
|
||||
$Publicdepartments = Department::getPublicDepartmentNames();
|
||||
|
||||
$isValid = false;
|
||||
|
||||
foreach($Publicdepartments as $department) {
|
||||
if($department['id'] == $departmentId){
|
||||
$isValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$isValid) throw new Exception(ERRORS::INVALID_DEFAULT_DEPARTMENT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
155
dist/api/controllers/system/email-polling.php
vendored
Executable file
155
dist/api/controllers/system/email-polling.php
vendored
Executable file
@ -0,0 +1,155 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
class EmailPollingController extends Controller {
|
||||
const PATH = '/email-polling';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $mailbox;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => [
|
||||
'token' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TOKEN, LengthConfig::MAX_LENGTH_TOKEN),
|
||||
'error' => ERRORS::INVALID_TOKEN
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$commentController = new CommentController();
|
||||
$createController = new CreateController();
|
||||
$defaultLanguage = Setting::getSetting('language')->getValue();
|
||||
$defaultDepartmentId = Department::getAll()->first()->id;
|
||||
|
||||
|
||||
if(Controller::request('token') !== Setting::getSetting('imap-token')->getValue())
|
||||
throw new RequestException(ERRORS::INVALID_TOKEN);
|
||||
|
||||
|
||||
$this->mailbox = new \PhpImap\Mailbox(
|
||||
Setting::getSetting('imap-host')->getValue(),
|
||||
Setting::getSetting('imap-user')->getValue(),
|
||||
Setting::getSetting('imap-pass')->getValue(),
|
||||
'files/'
|
||||
);
|
||||
|
||||
$errors = [];
|
||||
$emails = $this->getLastEmails();
|
||||
|
||||
$session = Session::getInstance();
|
||||
$oldSession = [
|
||||
'userId' => $session->getUserId(),
|
||||
'staff' => $session->getToken(),
|
||||
'token' => $session->isStaffLogged(),
|
||||
];
|
||||
|
||||
foreach($emails as $email) {
|
||||
Controller::setDataRequester(function ($key) use ($email, $defaultDepartmentId, $defaultLanguage) {
|
||||
switch ($key) {
|
||||
case 'ticketNumber':
|
||||
return $email->getTicketNumber();
|
||||
case 'title':
|
||||
return $email->getSubject();
|
||||
case 'content':
|
||||
return $email->getContent();
|
||||
case 'departmentId':
|
||||
return $defaultDepartmentId;
|
||||
case 'language':
|
||||
return $defaultLanguage;
|
||||
case 'email':
|
||||
return $email->getSender();
|
||||
case 'name':
|
||||
return $email->getSenderName();
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
/*
|
||||
if($email->getAttachment()) {
|
||||
$attachment = $email->getAttachment();
|
||||
$_FILES['file'] = [
|
||||
'name' => $attachment->name,
|
||||
'type' => mime_content_type($attachment->filePath),
|
||||
'tmp_name' => $attachment->filePath,
|
||||
'error' => UPLOAD_ERR_OK,
|
||||
'size' => filesize($attachment->filePath),
|
||||
];
|
||||
}
|
||||
*/
|
||||
|
||||
try {
|
||||
if($email->isReply()) {
|
||||
$ticketAuthor = $email->getTicket()->authorToArray();
|
||||
if($ticketAuthor['email'] === $email->getSender()) {
|
||||
$session->clearSessionData();
|
||||
$session->createSession($ticketAuthor['id'],
|
||||
$ticketAuthor['staff'],
|
||||
$email->getTicket()->ticketNumber);
|
||||
|
||||
$commentController->handler();
|
||||
}
|
||||
} else {
|
||||
$createController->handler();
|
||||
}
|
||||
} catch(\Exception $e) {
|
||||
$errors[] = [
|
||||
'author' => $email->getSender(),
|
||||
'ticketNumber' => $email->getTicketNumber(),
|
||||
'error' => $e->__toString(),
|
||||
];
|
||||
}
|
||||
|
||||
unset($_FILES['file']);
|
||||
}
|
||||
|
||||
$session->clearSessionData();
|
||||
$session->setSessionData($oldSession);
|
||||
|
||||
if(count($errors)) {
|
||||
Response::respondError(ERRORS::EMAIL_POLLING, null, $errors);
|
||||
} else {
|
||||
$this->eraseAllEmails();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
public function getLastEmails() {
|
||||
$mailsIds = $this->mailbox->searchMailbox('ALL');
|
||||
$emails = [];
|
||||
sort($mailsIds);
|
||||
|
||||
foreach($mailsIds as $mailId) {
|
||||
$mail = $this->mailbox->getMail($mailId);
|
||||
$mailHeader = $this->mailbox->getMailHeader($mailId);
|
||||
// $mailAttachment = count($mail->getAttachments()) ? current($mail->getAttachments()) : null;
|
||||
|
||||
$emails[] = new Email([
|
||||
'fromAddress' => $mailHeader->fromAddress,
|
||||
'fromName' => $mailHeader->fromName,
|
||||
'subject' => $mailHeader->subject,
|
||||
'content' => $mail->textPlain,
|
||||
'file' => null,
|
||||
]);
|
||||
|
||||
foreach($mail->getAttachments() as $attachment) {
|
||||
unlink($attachment->filePath);
|
||||
}
|
||||
}
|
||||
|
||||
return $emails;
|
||||
}
|
||||
|
||||
public function eraseAllEmails() {
|
||||
$mailsIds = $this->mailbox->searchMailbox('ALL');
|
||||
|
||||
foreach($mailsIds as $mailId) {
|
||||
$this->mailbox->deleteMail($mailId);
|
||||
}
|
||||
|
||||
$this->mailbox->expungeDeletedMails();
|
||||
}
|
||||
}
|
50
dist/api/controllers/system/enable-mandatory-login.php
vendored
Executable file
50
dist/api/controllers/system/enable-mandatory-login.php
vendored
Executable file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api {post} /system/enable-mandatory-login Enable mandatory Login
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Enable Mandatory Login
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path enable the mandatory Login.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} password The password of the current staff.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PASSWORD
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EnableMandatoryLoginController extends Controller {
|
||||
const PATH = '/enable-mandatory-login';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$password = Controller::request('password');
|
||||
|
||||
if(!Hashing::verifyPassword($password, Controller::getLoggedUser()->password)) {
|
||||
throw new RequestException(ERRORS::INVALID_PASSWORD);
|
||||
return;
|
||||
}
|
||||
|
||||
$mandatoryLoginRow = Setting::getSetting('mandatory-login');
|
||||
|
||||
$mandatoryLoginRow->value = 1;
|
||||
$mandatoryLoginRow->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
51
dist/api/controllers/system/enable-registration.php
vendored
Executable file
51
dist/api/controllers/system/enable-registration.php
vendored
Executable file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/enable-registration Enable registration
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Enable registration
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path enables the registration.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} password The password of the current staff.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PASSWORD
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EnableRegistrationController extends Controller {
|
||||
const PATH = '/enable-registration';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$password = Controller::request('password');
|
||||
|
||||
if(!Hashing::verifyPassword($password,Controller::getLoggedUser()->password)) {
|
||||
throw new RequestException(ERRORS::INVALID_PASSWORD);
|
||||
return;
|
||||
}
|
||||
|
||||
$registrationRow = Setting::getSetting('registration');
|
||||
|
||||
$registrationRow->value = true;
|
||||
$registrationRow->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
37
dist/api/controllers/system/get-api-keys.php
vendored
Executable file
37
dist/api/controllers/system/get-api-keys.php
vendored
Executable file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/get-api-keys Get APIKeys
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get APIKeys
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path retrieves the all APIKeys.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[APIKey](#api-Data_Structures-ObjectApikey)[]} data Array of APIKeys
|
||||
*
|
||||
*/
|
||||
|
||||
class GetAPIKeysController extends Controller {
|
||||
const PATH = '/get-api-keys';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$apiList = APIKey::getAll();
|
||||
Response::respondSuccess($apiList->toArray());
|
||||
}
|
||||
}
|
38
dist/api/controllers/system/get-custom-fields.php
vendored
Executable file
38
dist/api/controllers/system/get-custom-fields.php
vendored
Executable file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/get-custom-fields Get custom fields
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get all Custom field items
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path retrieves the all CustomField items.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[Customfield](#api-Data_Structures-ObjectCustomfield)[]} data Array of Customfield
|
||||
*
|
||||
*/
|
||||
|
||||
class GetCustomFieldsController extends Controller {
|
||||
const PATH = '/get-custom-fields';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$customFieldList = Customfield::getAll();
|
||||
|
||||
Response::respondSuccess($customFieldList->toArray());
|
||||
}
|
||||
}
|
58
dist/api/controllers/system/get-logs.php
vendored
Executable file
58
dist/api/controllers/system/get-logs.php
vendored
Executable file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
/**
|
||||
* @api {post} /system/get-logs Get logs
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get logs
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path retrieves the all the logs.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} page The page of logs.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PAGE
|
||||
*
|
||||
* @apiSuccess {[Log](#api-Data_Structures-ObjectLog)[]} data Array of last logs
|
||||
*
|
||||
*/
|
||||
|
||||
class GetLogsController extends Controller {
|
||||
const PATH = '/get-logs';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::numeric(),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->deleteLastLogs();
|
||||
$page = Controller::request('page');
|
||||
$logList = Log::find('ORDER BY id desc LIMIT ? OFFSET ?', [10, 10*($page-1)]);
|
||||
|
||||
Response::respondSuccess($logList->toArray());
|
||||
}
|
||||
|
||||
public function deleteLastLogs() {
|
||||
$removeOlderThanDays = 31;
|
||||
$oldDate = floor(Date::getPreviousDate($removeOlderThanDays) / 10000);
|
||||
|
||||
try {
|
||||
RedBean::exec("DELETE FROM log WHERE date < $oldDate");
|
||||
} catch(Exception $e) {}
|
||||
}
|
||||
}
|
36
dist/api/controllers/system/get-mail-template-list.php
vendored
Executable file
36
dist/api/controllers/system/get-mail-template-list.php
vendored
Executable file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/get-mail-template-list Get mail template
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get mail template list
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @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 GetMailTemplateListController extends Controller {
|
||||
const PATH = '/get-mail-template-list';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
Response::respondSuccess(array_keys(MailTemplate::getFilePaths()));
|
||||
}
|
||||
}
|
57
dist/api/controllers/system/get-mail-template.php
vendored
Executable file
57
dist/api/controllers/system/get-mail-template.php
vendored
Executable file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/get-mail-template Get mail template
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get mail template
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path retrieves the data of one of the mail templates.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} template The type of template to retrieve.
|
||||
* @apiParam {String} language The language of the template to retrieve.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[MailTemplate](#api-Data_Structures-ObjectMailtemplate)} data Data of the mail template
|
||||
*
|
||||
*/
|
||||
|
||||
class GetMailTemplateController extends Controller {
|
||||
const PATH = '/get-mail-template';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'template' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TEMPLATE),
|
||||
'error' => ERRORS::INVALID_TEMPLATE
|
||||
],
|
||||
'language' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(Language::getSupportedLanguages()), DataValidator::nullType()),
|
||||
'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 RequestException(ERRORS::INVALID_TEMPLATE);
|
||||
}
|
||||
|
||||
Response::respondSuccess($mailTemplate->toArray());
|
||||
}
|
||||
}
|
88
dist/api/controllers/system/get-settings.php
vendored
Executable file
88
dist/api/controllers/system/get-settings.php
vendored
Executable file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api {post} /system/get-settings Get settings
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get settings
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path retrieves all the settings.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {Boolean} allSettings Indicates if you want the regular settings list or a complete settings list. Complete list only available for staff level3.
|
||||
*
|
||||
* @apiSuccess {Object} data Contains the information about the settings
|
||||
*
|
||||
*/
|
||||
|
||||
class GetSettingsController extends Controller {
|
||||
const PATH = '/get-settings';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$settingsList = [];
|
||||
|
||||
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(),
|
||||
'maintenance-mode' => intval(Setting::getSetting('maintenance-mode')->getValue()),
|
||||
'layout' => Setting::getSetting('layout')->getValue(),
|
||||
'allow-attachments' => intval(Setting::getSetting('allow-attachments')->getValue()),
|
||||
'max-size' => Setting::getSetting('max-size')->getValue(),
|
||||
'url' => Setting::getSetting('url')->getValue(),
|
||||
'title' => Setting::getSetting('title')->getValue(),
|
||||
'server-email' => Setting::getSetting('server-email')->getValue(),
|
||||
'smtp-host' => Setting::getSetting('smtp-host')->getValue(),
|
||||
'smtp-user' => Setting::getSetting('smtp-user')->getValue(),
|
||||
'imap-host' => Setting::getSetting('imap-host')->getValue(),
|
||||
'imap-user' => Setting::getSetting('imap-user')->getValue(),
|
||||
'imap-token' => Setting::getSetting('imap-token')->getValue(),
|
||||
'registration' => Setting::getSetting('registration')->getValue(),
|
||||
'departments' => Department::getAllDepartmentNames(),
|
||||
'supportedLanguages' => Language::getSupportedLanguages(),
|
||||
'allowedLanguages' => Language::getAllowedLanguages(),
|
||||
'session-prefix' => Setting::getSetting('session-prefix')->getValue(),
|
||||
'mail-template-header-image' => Setting::getSetting('mail-template-header-image')->getValue(),
|
||||
'tags' => Tag::getAll()->toArray(),
|
||||
'mandatory-login' => Setting::getSetting('mandatory-login')->getValue(),
|
||||
'default-department-id' => Setting::getSetting('default-department-id')->getValue(),
|
||||
'default-is-locked' => Setting::getSetting('default-is-locked')->getValue()
|
||||
];
|
||||
} else {
|
||||
$settingsList = [
|
||||
'language' => Setting::getSetting('language')->getValue(),
|
||||
'reCaptchaKey' => Setting::getSetting('recaptcha-public')->getValue(),
|
||||
'maintenance-mode' => intval(Setting::getSetting('maintenance-mode')->getValue()),
|
||||
'layout' => Setting::getSetting('layout')->getValue(),
|
||||
'allow-attachments' => intval(Setting::getSetting('allow-attachments')->getValue()),
|
||||
'max-size' => Setting::getSetting('max-size')->getValue(),
|
||||
'title' => Setting::getSetting('title')->getValue(),
|
||||
'registration' => Setting::getSetting('registration')->getValue(),
|
||||
'departments' => Controller::isStaffLogged() ? Department::getAllDepartmentNames() : Department::getPublicDepartmentNames(),
|
||||
'supportedLanguages' => Language::getSupportedLanguages(),
|
||||
'allowedLanguages' => Language::getAllowedLanguages(),
|
||||
'session-prefix' => Setting::getSetting('session-prefix')->getValue(),
|
||||
'tags' => Tag::getAll()->toArray(),
|
||||
'mandatory-login' => Setting::getSetting('mandatory-login')->getValue(),
|
||||
'default-department-id' => Setting::getSetting('default-department-id')->getValue(),
|
||||
'default-is-locked' => Setting::getSetting('default-is-locked')->getValue()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Response::respondSuccess($settingsList);
|
||||
}
|
||||
}
|
80
dist/api/controllers/system/init-admin.php
vendored
Executable file
80
dist/api/controllers/system/init-admin.php
vendored
Executable file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /system/init-admin Init admin
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Init admin
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path creates the main administrator account. It can only be used once during installation
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {String} name Name of the administrator.
|
||||
* @apiParam {String} email Email of the administrator.
|
||||
* @apiParam {String} password Password of the administrator.
|
||||
*
|
||||
* @apiUse INVALID_NAME
|
||||
* @apiUse INVALID_EMAIL
|
||||
* @apiUse INVALID_PASSWORD
|
||||
* @apiUse INIT_SETTINGS_DONE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class InitAdminController extends Controller {
|
||||
const PATH = '/init-admin';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
],
|
||||
'email' => [
|
||||
'validation' => DataValidator::email(),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
],
|
||||
'password' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_PASSWORD, LengthConfig::MAX_LENGTH_PASSWORD),
|
||||
'error' => ERRORS::INVALID_PASSWORD
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if(!Staff::isTableEmpty()) {
|
||||
throw new RequestException(ERRORS::INIT_SETTINGS_DONE);
|
||||
}
|
||||
|
||||
$staff = new Staff();
|
||||
$staff->setProperties([
|
||||
'name' => Controller::request('name'),
|
||||
'email' => Controller::request('email'),
|
||||
'password' => Hashing::hashPassword(Controller::request('password')),
|
||||
'profilePic' => '',
|
||||
'level' => 3,
|
||||
'sharedDepartmentList' => Department::getAll(),
|
||||
'sharedTicketList' => [],
|
||||
'sendEmailOnNewTicket' => 1
|
||||
]);
|
||||
|
||||
foreach(Department::getAll() as $department) {
|
||||
$department->owners++;
|
||||
$department->store();
|
||||
}
|
||||
|
||||
$staff->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
84
dist/api/controllers/system/init-database.php
vendored
Executable file
84
dist/api/controllers/system/init-database.php
vendored
Executable file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
/**
|
||||
* @api {post} /system/init-database Init database
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Init database
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path sets the database settings. It can only be used once during installation.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {String} dbHost Location of the database server.
|
||||
* @apiParam {String} dbPort Port of the database server.
|
||||
* @apiParam {String} dbName Name of the database. If not given, the system will try to create one.
|
||||
* @apiParam {String} dbUser User of the database server.
|
||||
* @apiParam {String} dbPassword Password of the database server.
|
||||
*
|
||||
* @apiUse DATABASE_CONNECTION
|
||||
* @apiUse DATABASE_CREATION
|
||||
* @apiUse INVALID_FILE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class InitDatabaseController extends Controller {
|
||||
const PATH = '/init-database';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if(defined('MYSQL_HOST')) {
|
||||
throw new RequestException(ERRORS::INIT_SETTINGS_DONE);
|
||||
}
|
||||
|
||||
$dbHost = Controller::request('dbHost');
|
||||
$dbPort = Controller::request('dbPort');
|
||||
$dbName = Controller::request('dbName');
|
||||
$dbUser = Controller::request('dbUser');
|
||||
$dbPass = Controller::request('dbPassword');
|
||||
|
||||
RedBean::setup("mysql:host=$dbHost;port=$dbPort", $dbUser, $dbPass);
|
||||
|
||||
if($dbName) {
|
||||
RedBean::addDatabase($dbName, "mysql:host=$dbHost;port=$dbPort;dbname=$dbName", $dbUser, $dbPass);
|
||||
RedBean::selectDatabase($dbName);
|
||||
|
||||
if(!RedBean::testConnection()) {
|
||||
throw new RequestException(ERRORS::DATABASE_CONNECTION);
|
||||
}
|
||||
} else {
|
||||
$dbName = 'opensupports_' . Hashing::generateRandomNumber(100, 999);
|
||||
RedBean::exec('CREATE DATABASE ' . $dbName);
|
||||
RedBean::addDatabase($dbName, "mysql:host=$dbHost;port=$dbPort;dbname=$dbName", $dbUser, $dbPass);
|
||||
RedBean::selectDatabase($dbName);
|
||||
|
||||
if(!RedBean::testConnection()) {
|
||||
throw new RequestException(ERRORS::DATABASE_CREATION);
|
||||
}
|
||||
}
|
||||
|
||||
$configFile = fopen('config.php', 'w+') or die(ERRORS::INVALID_FILE);
|
||||
$content = '<?php' . PHP_EOL;
|
||||
$content .= 'define(\'MYSQL_HOST\', \'' . $dbHost . '\');' . PHP_EOL;
|
||||
$content .= 'define(\'MYSQL_PORT\', \'' . $dbPort . '\');' . PHP_EOL;
|
||||
$content .= 'define(\'MYSQL_USER\', \'' . $dbUser . '\');' . PHP_EOL;
|
||||
$content .= 'define(\'MYSQL_PASSWORD\', \'' . $dbPass . '\');' . PHP_EOL;
|
||||
$content .= 'define(\'MYSQL_DATABASE\', \'' . $dbName . '\');' . PHP_EOL;
|
||||
|
||||
fwrite($configFile, $content);
|
||||
fclose($configFile);
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
156
dist/api/controllers/system/init-settings.php
vendored
Executable file
156
dist/api/controllers/system/init-settings.php
vendored
Executable file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /system/init-settings Init settings
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Init settings
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path sets the initial settings. It can only be used once during installation.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {String} language Indicates the default language of the system.
|
||||
* @apiParam {String} registration Indicates if the registration should be enabled.
|
||||
* @apiParam {String} server-email Email from where automated emails will be sent.
|
||||
* @apiParam {String} smtp-host SMTP Server address.
|
||||
* @apiParam {String} smtp-user SMTP Authentication User.
|
||||
* @apiParam {String} smtp-pass SMTP Authentication Password.
|
||||
* @apiParam {String} allow-attachments Indicates if files can be attached to tickets and comments.
|
||||
* @apiParam {String} title Title of the support center
|
||||
* @apiParam {String} url Url of the frontend client.
|
||||
* @apiParam {Boolean} mandatory-login Indicates if the login is mandatory.
|
||||
* @apiUse INVALID_LANGUAGE
|
||||
* @apiUse INIT_SETTINGS_DONE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class InitSettingsController extends Controller {
|
||||
const PATH = '/init-settings';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => [
|
||||
'language' => [
|
||||
'validation' => DataValidator::validLanguage(),
|
||||
'error' => ERRORS::INVALID_LANGUAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if (Setting::isTableEmpty()) {
|
||||
RedBean::exec(file_get_contents('data/db_schema.sql'));
|
||||
$this->storeGlobalSettings();
|
||||
$this->storeMailTemplates();
|
||||
$this->storeLanguages();
|
||||
$this->storeMockedDepartments();
|
||||
|
||||
Response::respondSuccess();
|
||||
} else {
|
||||
throw new RequestException(ERRORS::INIT_SETTINGS_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
private function storeGlobalSettings() {
|
||||
$this->storeSettings([
|
||||
'language' => Controller::request('language'),
|
||||
'recaptcha-public' => '',
|
||||
'recaptcha-private' => '',
|
||||
'server-email' => Controller::request('server-email'),
|
||||
'imap-host' => Controller::request('imap-host'),
|
||||
'imap-user' => Controller::request('imap-user'),
|
||||
'imap-pass' => Controller::request('imap-pass'),
|
||||
'smtp-host' => Controller::request('smtp-host'),
|
||||
'smtp-user' => Controller::request('smtp-user'),
|
||||
'smtp-pass' => Controller::request('smtp-pass'),
|
||||
'maintenance-mode' => 0,
|
||||
'layout' => 'boxed',
|
||||
'allow-attachments' => !!Controller::request('allow-attachments'),
|
||||
'max-size' => 1,
|
||||
'title' => Controller::request('title') ? Controller::request('title') : 'Support Center',
|
||||
'url' => Controller::request('url') ? Controller::request('url') : ('http://' . $_SERVER['HTTP_HOST']),
|
||||
'registration' => !!Controller::request('registration'),
|
||||
'last-stat-day' => date('YmdHi', strtotime(' -12 day ')),
|
||||
'ticket-gap' => Hashing::generateRandomPrime(100000, 999999),
|
||||
'ticket-first-number' => Hashing::generateRandomNumber(100000, 999999),
|
||||
'session-prefix' => 'opensupports-'.Hashing::generateRandomToken().'_',
|
||||
'mail-template-header-image' => 'https://s3.amazonaws.com/opensupports/logo.png',
|
||||
'default-department-id' => 1,
|
||||
'default-is-locked' => false,
|
||||
'imap-token' => '',
|
||||
'mandatory-login' => !!Controller::request('mandatory-login')
|
||||
]);
|
||||
}
|
||||
|
||||
private function storeMailTemplates() {
|
||||
$mailLanguages = MailTexts::getTexts();
|
||||
|
||||
foreach ($mailLanguages as $language => $mailTemplate) {
|
||||
foreach ($mailTemplate as $template => $texts) {
|
||||
$mailTemplate = new MailTemplate();
|
||||
|
||||
$mailTemplate->setProperties([
|
||||
'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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function storeSettings($settings) {
|
||||
foreach ($settings as $settingName => $settingValue) {
|
||||
$setting = new Setting();
|
||||
$setting->setProperties([
|
||||
'name' => $settingName,
|
||||
'value' => $settingValue
|
||||
]);
|
||||
|
||||
$setting->store();
|
||||
}
|
||||
}
|
||||
private function storeLanguages() {
|
||||
$defaultLanguage = Controller::request('language');
|
||||
|
||||
foreach(Language::LANGUAGES as $languageCode) {
|
||||
$language = new Language();
|
||||
$language->setProperties([
|
||||
'code' => $languageCode,
|
||||
'allowed' => 1,
|
||||
'supported' => ($languageCode === $defaultLanguage)
|
||||
]);
|
||||
|
||||
$language->store();
|
||||
}
|
||||
}
|
||||
|
||||
private function storeMockedDepartments() {
|
||||
$departments = [
|
||||
'Help and Support'
|
||||
];
|
||||
|
||||
foreach ($departments as $departmentName) {
|
||||
$department = new Department();
|
||||
$department->name = $departmentName;
|
||||
$department->private = 0;
|
||||
$department->store();
|
||||
}
|
||||
}
|
||||
}
|
42
dist/api/controllers/system/installation-done.php
vendored
Executable file
42
dist/api/controllers/system/installation-done.php
vendored
Executable file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
/**
|
||||
* @api {post} /system/installation-done Installation done
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Installation done
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path checks if the installation is already done.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiSuccess {Boolean} data Indicates if the installation is already done.
|
||||
*
|
||||
*/
|
||||
|
||||
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',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if(InstallationDoneController::isInstallationDone()) {
|
||||
Response::respondSuccess(1);
|
||||
} else {
|
||||
Response::respondSuccess(0);
|
||||
}
|
||||
}
|
||||
}
|
68
dist/api/controllers/system/recover-mail-template.php
vendored
Executable file
68
dist/api/controllers/system/recover-mail-template.php
vendored
Executable file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/recover-mail-template Recover mail template
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Recover mail template
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path recovers an mail template to its original content.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {String} template Type of the template.
|
||||
* @apiParam {String} language Lenguage of the template.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TEMPLATE
|
||||
* @apiUse INVALID_LANGUAGE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class RecoverMailTemplateController extends Controller {
|
||||
const PATH = '/recover-mail-template';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'template' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TEMPLATE),
|
||||
'error' => ERRORS::INVALID_TEMPLATE
|
||||
],
|
||||
'language' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(Language::getSupportedLanguages()), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_LANGUAGE
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$templateType = Controller::request('template');
|
||||
$language = Controller::request('language');
|
||||
|
||||
$mailTemplate = MailTemplate::findOne(' language = ? AND template = ?', [$language, $templateType]);
|
||||
|
||||
if($mailTemplate->isNull()) {
|
||||
throw new RequestException(ERRORS::INVALID_TEMPLATE);
|
||||
}
|
||||
|
||||
$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();
|
||||
}
|
||||
}
|
375
dist/api/controllers/system/stats.php
vendored
Executable file
375
dist/api/controllers/system/stats.php
vendored
Executable file
@ -0,0 +1,375 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
/**
|
||||
* @api {post} /system/get-stats Get overall stats
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Stats
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription This path retrieves the last stats.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number[]} tags The ids of the tags for the custom stats.
|
||||
* @apiParam {Number[]} dateRange The array with start and end date of the range for the custom stats.
|
||||
* @apiParam {Number[]} departments The ids of the departments for the custom stats.
|
||||
* @apiParam {Number[]} owners The ids of the owners for the custom stats.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_DEPARTMENT_FILTER
|
||||
* @apiUse INVALID_DATE_RANGE_FILTER
|
||||
* @apiUse INVALID_OWNER_FILTER
|
||||
*
|
||||
* @apiSuccess {[StatList](#api-Data_Structures-ObjectStatlist)[]} data Array of the stats
|
||||
*
|
||||
*/
|
||||
|
||||
class GetStatsController extends Controller {
|
||||
const PATH = '/get-stats';
|
||||
const METHOD = 'POST';
|
||||
private $table;
|
||||
private $groupBy;
|
||||
|
||||
private $dateRangeFilter;
|
||||
private $departmentsFilter;
|
||||
private $tagsFilter;
|
||||
private $ownersFilter;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'dateRange' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validDateRange(), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_DATE_RANGE_FILTER
|
||||
],
|
||||
'departments' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validDepartmentsId(), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT_FILTER
|
||||
],
|
||||
'tags' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validTagsId(), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_TAG_FILTER
|
||||
],
|
||||
'owners' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validOwnersId(), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_OWNER_FILTER
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->table = " ticket LEFT JOIN ticketevent ON ticket.id = ticketevent.ticket_id
|
||||
LEFT JOIN tag_ticket ON ticket.id = tag_ticket.ticket_id ";
|
||||
$this->groupBy = " GROUP BY ticket.id ";
|
||||
$this->dateRangeFilter = $this->addDateRangeFilter();
|
||||
$this->departmentsFilter = $this->addDepartmentsFilter();
|
||||
$this->tagsFilter = $this->addTagsFilter();
|
||||
$this->ownersFilter = $this->addOwnersFilter();
|
||||
|
||||
Response::respondSuccess([
|
||||
'created' => $this->getNumberOfCreatedTickets(),
|
||||
'open' => $this->getNumberOfOpenTickets(),
|
||||
'closed' => $this->getNumberOfClosedTickets(),
|
||||
'instant' => $this->getNumberOfInstantTickets(),
|
||||
'reopened' => $this->getNumberOfReopenedTickets(),
|
||||
'created_by_hour' => $this->getNumberOfCreatedTicketsByHour(),
|
||||
'created_by_weekday' => $this->getNumberOfCreatedTicketsByWeekday(),
|
||||
'average_first_reply' => $this->getAverageFirstReply(),
|
||||
'average_first_closed' => $this->getAverageFirstClosed(),
|
||||
'average_last_closed' => $this->getAverageLastClosed(),
|
||||
'average_department_hops' => $this->getAverageDepartmentHops(),
|
||||
'average_staff_hops' => $this->getAverageStaffHops()
|
||||
]);
|
||||
}
|
||||
|
||||
// This function assumes there is a previous condition
|
||||
private function addDateRangeFilter() {
|
||||
$dateRange = json_decode(Controller::request('dateRange'));
|
||||
if ($dateRange === NULL) return " ";
|
||||
$sql = " AND ticket.date >= {$dateRange[0]} AND ticket.date <= {$dateRange[1]} ";
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// This function assumes there is a previous condition
|
||||
private function addDepartmentsFilter() {
|
||||
$departments = json_decode(Controller::request('departments'));
|
||||
if ($departments === NULL || empty($departments)) return " ";
|
||||
$sql = " AND ";
|
||||
for ($i = 0; $i < count($departments); ++$i) {
|
||||
$departmentId = $departments[$i];
|
||||
$departments[$i] = " ticket.department_id={$departmentId} ";
|
||||
}
|
||||
$sql .= '(' . join(" OR ", $departments) . ')';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// This function assumes there is a previous condition
|
||||
private function addTagsFilter() {
|
||||
$tags = json_decode(Controller::request('tags'));
|
||||
if ($tags === NULL || empty($tags)) return " ";
|
||||
$sql = " AND ";
|
||||
for ($i = 0; $i < count($tags); ++$i) {
|
||||
$tagId = $tags[$i];
|
||||
$tags[$i] = " tag_ticket.tag_id={$tagId} ";
|
||||
}
|
||||
$sql .= '(' . join(" OR ", $tags) . ')';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
// This function assumes there is a previous condition
|
||||
private function addOwnersFilter() {
|
||||
$owners = json_decode(Controller::request('owners'));
|
||||
if ($owners === NULL || empty($owners)) return " ";
|
||||
$sql = " AND ";
|
||||
for ($i = 0; $i < count($owners); ++$i) {
|
||||
$ownerId = $owners[$i];
|
||||
$owners[$i] = " ticket.owner_id={$ownerId} ";
|
||||
}
|
||||
$sql .= '(' . join(" OR ", $owners) . ')';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function getNumberOfCreatedTickets() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT COUNT(*) FROM {$this->table} WHERE 1=1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
public function getNumberOfOpenTickets() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT COUNT(*) FROM {$this->table} WHERE closed=0
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
public function getNumberOfClosedTickets() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT COUNT(*) FROM {$this->table} WHERE closed=1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
public function getNumberOfInstantTickets() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
{$this->table}
|
||||
WHERE
|
||||
ticketevent.type = 'COMMENT'
|
||||
AND ticketevent.author_staff_id
|
||||
AND private = 0
|
||||
AND closed = 1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}
|
||||
HAVING COUNT(*) = 1) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
public function getNumberOfReopenedTickets() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT
|
||||
COUNT(*)
|
||||
FROM
|
||||
(SELECT COUNT(*) FROM {$this->table} WHERE reopened=1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
// Returns an array of size 24 with the number of tickets created for each hour
|
||||
public function getNumberOfCreatedTicketsByHour() {
|
||||
$result = RedBean::getAll("
|
||||
SELECT
|
||||
VALID_TICKETS.HOUR_DAY, COUNT(RAW_CNT) AS CNT
|
||||
FROM
|
||||
(SELECT
|
||||
COUNT(*) AS RAW_CNT,
|
||||
ticket.date % 10000 DIV 100 AS HOUR_DAY
|
||||
FROM {$this->table} WHERE 1=1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS VALID_TICKETS
|
||||
GROUP BY VALID_TICKETS.HOUR_DAY;
|
||||
");
|
||||
|
||||
$ans = array_fill(0, 24, 0);
|
||||
for ($i = 0; $i < count($result); ++$i) {
|
||||
$hour = (int)$result[$i]["HOUR_DAY"];
|
||||
$cnt = (int)$result[$i]["CNT"];
|
||||
$ans[$hour] = $cnt;
|
||||
}
|
||||
return $ans;
|
||||
}
|
||||
|
||||
// Returns an array of size 7 with the number of tickets created by weekday (0 - monday, ..., 6 - sunday)
|
||||
public function getNumberOfCreatedTicketsByWeekday() {
|
||||
$result = RedBean::getAll("
|
||||
SELECT
|
||||
VALID_TICKETS.WEEK_DAY, COUNT(RAW_CNT) AS CNT
|
||||
FROM
|
||||
(SELECT
|
||||
COUNT(*) AS RAW_CNT, WEEKDAY(STR_TO_DATE(CONVERT(ticket.date, CHAR), '%Y%m%d%H%i')) AS WEEK_DAY
|
||||
FROM {$this->table} WHERE 1 = 1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS VALID_TICKETS
|
||||
GROUP BY VALID_TICKETS.WEEK_DAY;
|
||||
");
|
||||
|
||||
$ans = array_fill(0, 7, 0);
|
||||
for ($i = 0; $i < count($result); ++$i) {
|
||||
$hour = (int)$result[$i]["WEEK_DAY"];
|
||||
$cnt = (int)$result[$i]["CNT"];
|
||||
$ans[$hour] = $cnt;
|
||||
}
|
||||
|
||||
return $ans;
|
||||
}
|
||||
|
||||
// Returns the number of seconds (as int), on average, that a ticket waits for the first reply of a staff
|
||||
public function getAverageFirstReply() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT AVG(SECS)
|
||||
FROM (
|
||||
SELECT
|
||||
ticket.id,
|
||||
UNIX_TIMESTAMP(STR_TO_DATE(CONVERT(MIN(ticketevent.date), CHAR), '%Y%m%d%H%i')) -
|
||||
UNIX_TIMESTAMP(STR_TO_DATE(CONVERT(ticket.date, CHAR), '%Y%m%d%H%i')) AS SECS
|
||||
FROM
|
||||
{$this->table}
|
||||
WHERE
|
||||
ticketevent.type = 'COMMENT'
|
||||
AND ticketevent.author_staff_id
|
||||
AND private = 0
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
// Returns the number of seconds (as int), on average, that a ticket waits until it's first closed
|
||||
public function getAverageFirstClosed() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT
|
||||
AVG(SECS)
|
||||
FROM
|
||||
(SELECT
|
||||
ticket.id,
|
||||
UNIX_TIMESTAMP(STR_TO_DATE(CONVERT( MIN(ticket.first_closed_at) , CHAR), '%Y%m%d%H%i')) - UNIX_TIMESTAMP(STR_TO_DATE(CONVERT( ticket.date , CHAR), '%Y%m%d%H%i')) AS SECS
|
||||
FROM
|
||||
{$this->table}
|
||||
WHERE
|
||||
first_closed_at IS NOT NULL
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
// Returns the number of seconds (as int), on average, that a ticket waits until it's closed for the last time
|
||||
public function getAverageLastClosed() {
|
||||
return (int) RedBean::getCell("
|
||||
SELECT
|
||||
AVG(SECS)
|
||||
FROM
|
||||
(SELECT
|
||||
ticket.id,
|
||||
UNIX_TIMESTAMP(STR_TO_DATE(CONVERT( MIN(ticket.last_closed_at) , CHAR), '%Y%m%d%H%i')) - UNIX_TIMESTAMP(STR_TO_DATE(CONVERT( ticket.date , CHAR), '%Y%m%d%H%i')) AS SECS
|
||||
FROM
|
||||
{$this->table}
|
||||
WHERE
|
||||
first_closed_at IS NOT NULL
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
// Returns the average number of departments (as double) a ticket has been in
|
||||
public function getAverageDepartmentHops() {
|
||||
return (double) RedBean::getCell("
|
||||
SELECT
|
||||
AVG(CNT)
|
||||
FROM
|
||||
(SELECT
|
||||
ticket.id, ticket.total_departments AS CNT
|
||||
FROM
|
||||
{$this->table}
|
||||
WHERE
|
||||
1 = 1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
|
||||
// Returns the average number of staff members a ticket has been assigned to
|
||||
public function getAverageStaffHops() {
|
||||
return (double) RedBean::getCell("
|
||||
SELECT
|
||||
AVG(CNT)
|
||||
FROM
|
||||
(SELECT
|
||||
ticket.id, ticket.total_owners AS CNT
|
||||
FROM
|
||||
{$this->table}
|
||||
WHERE
|
||||
1 = 1
|
||||
{$this->dateRangeFilter}
|
||||
{$this->departmentsFilter}
|
||||
{$this->tagsFilter}
|
||||
{$this->ownersFilter}
|
||||
{$this->groupBy}) AS Z;
|
||||
");
|
||||
}
|
||||
}
|
43
dist/api/controllers/system/test-imap.php
vendored
Executable file
43
dist/api/controllers/system/test-imap.php
vendored
Executable file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api {post} /system/test-imap Test IMAP Connection
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Test IMAP Connection
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription Test if the given values connect correctly to a IMAP server.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {String} imap-host Host of the IMAP server.
|
||||
* @apiParam {String} imap-user User for the IMAP server.
|
||||
* @apiParam {String} imap-pass Password for the IMAP server.
|
||||
*
|
||||
* @apiUse IMAP_CONNECTION
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class TestIMAPController extends Controller {
|
||||
const PATH = '/test-imap';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if(imap_open(Controller::request('imap-host'), Controller::request('imap-user'), Controller::request('imap-pass'))) {
|
||||
Response::respondSuccess();
|
||||
} else {
|
||||
throw new RequestException(ERRORS::IMAP_CONNECTION);
|
||||
}
|
||||
}
|
||||
}
|
52
dist/api/controllers/system/test-smtp.php
vendored
Executable file
52
dist/api/controllers/system/test-smtp.php
vendored
Executable file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /system/test-smtp Test SMTP Connection
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Test SMTP Connection
|
||||
*
|
||||
* @apiGroup System
|
||||
*
|
||||
* @apiDescription Test if the given values connect correctly to a SMTP server.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {String} smtp-host Host of the SMTP server.
|
||||
* @apiParam {String} smtp-user User for the SMTP server.
|
||||
* @apiParam {String} smtp-pass Password for the SMTP server.
|
||||
*
|
||||
* @apiUse SMTP_CONNECTION
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class TestSMTPController extends Controller {
|
||||
const PATH = '/test-smtp';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$mailSender = MailSender::getInstance();
|
||||
$mailSender->setConnectionSettings(
|
||||
Controller::request('smtp-host'),
|
||||
Controller::request('smtp-user'),
|
||||
Controller::request('smtp-pass'),
|
||||
''
|
||||
);
|
||||
|
||||
if($mailSender->isConnected()) {
|
||||
Response::respondSuccess();
|
||||
} else {
|
||||
throw new RequestException(ERRORS::SMTP_CONNECTION);
|
||||
}
|
||||
}
|
||||
}
|
30
dist/api/controllers/ticket.php
vendored
Executable file
30
dist/api/controllers/ticket.php
vendored
Executable file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
$ticketControllers = new ControllerGroup();
|
||||
$ticketControllers->setGroupPath('/ticket');
|
||||
|
||||
$ticketControllers->addController(new CreateController);
|
||||
$ticketControllers->addController(new EditCommentController);
|
||||
$ticketControllers->addController(new EditTitleController);
|
||||
$ticketControllers->addController(new CommentController);
|
||||
$ticketControllers->addController(new TicketGetController);
|
||||
$ticketControllers->addController(new CheckTicketController);
|
||||
$ticketControllers->addController(new AddCustomResponseController);
|
||||
$ticketControllers->addController(new DeleteCustomResponseController);
|
||||
$ticketControllers->addController(new EditCustomResponseController);
|
||||
$ticketControllers->addController(new GetCustomResponsesController);
|
||||
$ticketControllers->addController(new ChangeDepartmentController);
|
||||
$ticketControllers->addController(new CloseController);
|
||||
$ticketControllers->addController(new ReOpenController);
|
||||
$ticketControllers->addController(new SeenController);
|
||||
$ticketControllers->addController(new DeleteController);
|
||||
$ticketControllers->addController(new CreateTagController);
|
||||
$ticketControllers->addController(new EditTagController);
|
||||
$ticketControllers->addController(new DeleteTagController);
|
||||
$ticketControllers->addController(new GetTagsController);
|
||||
$ticketControllers->addController(new AddTagController);
|
||||
$ticketControllers->addController(new RemoveTagController);
|
||||
$ticketControllers->addController(new SearchController);
|
||||
$ticketControllers->addController(new SearchAuthorsController);
|
||||
$ticketControllers->addController(new GetAuthorsController);
|
||||
|
||||
$ticketControllers->finalize();
|
67
dist/api/controllers/ticket/add-custom-response.php
vendored
Executable file
67
dist/api/controllers/ticket/add-custom-response.php
vendored
Executable file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/add-custom-response Add custom responses
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Add a custom response
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path allows add new custom responses for tickets.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {String} name Name of the response.
|
||||
* @apiParam {String} content Content of the response.
|
||||
* @apiParam {String} language Language of the response.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_CONTENT
|
||||
* @apiUse INVALID_LANGUAGE
|
||||
* @apiUse INVALID_TITLE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class AddCustomResponseController extends Controller {
|
||||
const PATH = '/add-custom-response';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_TITLE
|
||||
],
|
||||
'content' => [
|
||||
'validation' => DataValidator::content(),
|
||||
'error' => ERRORS::INVALID_CONTENT
|
||||
],
|
||||
'language' => [
|
||||
'validation' => DataValidator::validLanguage(),
|
||||
'error' => ERRORS::INVALID_LANGUAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$customResponse = new CustomResponse();
|
||||
$customResponse->setProperties([
|
||||
'name' => Controller::request('name', true),
|
||||
'content' => Controller::request('content', true),
|
||||
'language' => Controller::request('language')
|
||||
]);
|
||||
$customResponse->store();
|
||||
|
||||
Log::createLog('ADD_CUSTOM_RESPONSE', null);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
64
dist/api/controllers/ticket/add-tag.php
vendored
Executable file
64
dist/api/controllers/ticket/add-tag.php
vendored
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/add-tag Add tag
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Add tag
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path attaches a new tag to a ticket.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of the ticket which the tag is going to be attached.
|
||||
* @apiParam {String} tagId The id of the tag to attach.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
* @apiUse INVALID_TAG
|
||||
* @apiUse TAG_EXISTS
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class AddTagController extends Controller {
|
||||
const PATH = '/add-tag';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
],
|
||||
'tagId' => [
|
||||
'validation' => DataValidator::dataStoreId('tag'),
|
||||
'error' => ERRORS::INVALID_TAG
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$tagId = Controller::request('tagId');
|
||||
$tag = Tag::getDataStore($tagId);
|
||||
$ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
if(!$user->canManageTicket($ticket)) throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
|
||||
if ($ticket->sharedTagList->includesId($tagId)) throw new RequestException(ERRORS::TAG_EXISTS);
|
||||
|
||||
$ticket->sharedTagList->add($tag);
|
||||
$ticket->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
91
dist/api/controllers/ticket/change-department.php
vendored
Executable file
91
dist/api/controllers/ticket/change-department.php
vendored
Executable file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/change-department Change department
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Change department
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path changes the department of a ticket.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of the ticket.
|
||||
* @apiParam {Number} departmentId The id of the new department of the ticket.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
* @apiUse INVALID_DEPARTMENT
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class ChangeDepartmentController extends Controller {
|
||||
const PATH = '/change-department';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
],
|
||||
'departmentId' => [
|
||||
'validation' => DataValidator::dataStoreId('department'),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$ticketNumber = Controller::request('ticketNumber');
|
||||
$departmentId = Controller::request('departmentId');
|
||||
$ticket = Ticket::getByTicketNumber($ticketNumber);
|
||||
$department = Department::getDataStore($departmentId);
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
if(!$ticket->authorStaffId && $department->private){
|
||||
throw new Exception(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if(!$user->canManageTicket($ticket)){
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if($ticket->department->id == $department->id){
|
||||
throw new RequestException(ERRORS::SAME_DEPARTMENT);
|
||||
}
|
||||
|
||||
if($ticket->owner && !$ticket->owner->sharedDepartmentList->includesId($department->id)) {
|
||||
$unAssignTicketController = new UnAssignStaffController($user);
|
||||
$unAssignTicketController->validate();
|
||||
$unAssignTicketController->handler();
|
||||
}
|
||||
|
||||
$ticket = Ticket::getByTicketNumber($ticketNumber);
|
||||
|
||||
$event = Ticketevent::getEvent(Ticketevent::DEPARTMENT_CHANGED);
|
||||
$event->setProperties(array(
|
||||
'authorStaff' => $user,
|
||||
'content' => $department->name,
|
||||
'date' => Date::getCurrentDate()
|
||||
));
|
||||
$ticket->addEvent($event);
|
||||
$ticket->department = $department;
|
||||
$ticket->totalDepartments++;
|
||||
$ticket->unread = !$ticket->isAuthor($user);
|
||||
$ticket->store();
|
||||
|
||||
Log::createLog('DEPARTMENT_CHANGED', $ticket->ticketNumber);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
79
dist/api/controllers/ticket/check.php
vendored
Executable file
79
dist/api/controllers/ticket/check.php
vendored
Executable file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/check Check ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Check ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path logs you in to see a ticket, but only when there is no users.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of a ticket.
|
||||
* @apiParam {String} email Email of the person who created the ticket.
|
||||
* @apiParam {String} captcha Encrypted value generated by google captcha client.
|
||||
*
|
||||
* @apiUse INVALID_TICKET
|
||||
* @apiUse INVALID_EMAIL
|
||||
* @apiUse INVALID_CAPTCHA
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {Object} data Data for the ticket session
|
||||
* @apiSuccess {String} data.token Token of the ticket session
|
||||
* @apiSuccess {Number} data.ticketNumber Number of the ticket
|
||||
*
|
||||
*/
|
||||
|
||||
class CheckTicketController extends Controller {
|
||||
const PATH = '/check';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
],
|
||||
'email' => [
|
||||
'validation' => DataValidator::email(),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
],
|
||||
'captcha' => [
|
||||
'validation' => DataValidator::captcha(APIKey::TICKET_CHECK_PERMISSION),
|
||||
'error' => ERRORS::INVALID_CAPTCHA
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
if (Controller::isLoginMandatory()) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
$email = Controller::request('email');
|
||||
$ticketNumber = Controller::request('ticketNumber');
|
||||
$ticket = Ticket::getByTicketNumber($ticketNumber);
|
||||
|
||||
if($ticket->authorEmail === $email) {
|
||||
$session = Session::getInstance();
|
||||
$user = User::getUser($email, 'email');
|
||||
|
||||
$session->createSession($user->id, false, $ticketNumber);
|
||||
Response::respondSuccess([
|
||||
'token' => $session->getToken(),
|
||||
'userId' => $session->getUserId(),
|
||||
'ticketNumber' => $session->getTicketNumber()
|
||||
]);
|
||||
} else {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
}
|
||||
}
|
103
dist/api/controllers/ticket/close.php
vendored
Executable file
103
dist/api/controllers/ticket/close.php
vendored
Executable file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/close Close ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Close
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path closes a ticket.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of a ticket.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class CloseController extends Controller {
|
||||
const PATH = '/close';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $ticket;
|
||||
|
||||
public function validations() {
|
||||
$session = Session::getInstance();
|
||||
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
if(!$user->canManageTicket($this->ticket)){
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
$this->markAsUnread();
|
||||
$this->addCloseEvent();
|
||||
$this->ticket->closed = true;
|
||||
if (!$this->ticket->first_closed_at) {
|
||||
$this->ticket->first_closed_at = Date::getCurrentDate();
|
||||
}
|
||||
$this->ticket->last_closed_at = Date::getCurrentDate();
|
||||
|
||||
$this->ticket->store();
|
||||
|
||||
$this->sendMail();
|
||||
Log::createLog('CLOSE', $this->ticket->ticketNumber);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
private function markAsUnread() {
|
||||
$this->ticket->unread = !$this->ticket->isAuthor(Controller::getLoggedUser());
|
||||
$this->ticket->unreadStaff = !$this->ticket->isOwner(Controller::getLoggedUser());
|
||||
}
|
||||
|
||||
private function addCloseEvent() {
|
||||
$event = Ticketevent::getEvent(Ticketevent::CLOSE);
|
||||
$event->setProperties(array(
|
||||
'date' => Date::getCurrentDate()
|
||||
));
|
||||
|
||||
if(Controller::isStaffLogged()) {
|
||||
$event->authorStaff = Controller::getLoggedUser();
|
||||
} else {
|
||||
$event->authorUser = Controller::getLoggedUser();
|
||||
}
|
||||
|
||||
$this->ticket->addEvent($event);
|
||||
}
|
||||
|
||||
private function sendMail() {
|
||||
$mailSender = MailSender::getInstance();
|
||||
|
||||
$mailSender->setTemplate(MailTemplate::TICKET_CLOSED, [
|
||||
'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()
|
||||
]);
|
||||
|
||||
$mailSender->send();
|
||||
}
|
||||
}
|
161
dist/api/controllers/ticket/comment.php
vendored
Executable file
161
dist/api/controllers/ticket/comment.php
vendored
Executable file
@ -0,0 +1,161 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/comment Comment ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Comment ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path comments a ticket.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} content Content of the comment.
|
||||
* @apiParam {Number} ticketNumber The number of the ticket to comment.
|
||||
* @apiParam {Boolean} private Indicates if the comment is not shown to users.
|
||||
* @apiParam {Number} images The number of images in the content.
|
||||
* @apiParam {String} apiKey apiKey to comment a ticket.
|
||||
* @apiParam image_i The image file of index `i` (mutiple params accepted)
|
||||
* @apiParam file The file you with to upload.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_CONTENT
|
||||
* @apiUse INVALID_TICKET
|
||||
* @apiUse INVALID_FILE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class CommentController extends Controller {
|
||||
const PATH = '/comment';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $ticket;
|
||||
private $content;
|
||||
private $session;
|
||||
private $imagePaths;
|
||||
|
||||
public function validations() {
|
||||
$validations = [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'content' => [
|
||||
'validation' => DataValidator::content(),
|
||||
'error' => ERRORS::INVALID_CONTENT
|
||||
],
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
if(Controller::request('captcha')){
|
||||
$validations['permission'] = 'any';
|
||||
$validations['requestData']['captcha'] = [
|
||||
'validation' => DataValidator::captcha(APIKey::TICKET_CREATE_PERMISSION),
|
||||
'error' => ERRORS::INVALID_CAPTCHA
|
||||
];
|
||||
}
|
||||
|
||||
return $validations;
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$ticketNumber = Controller::request('ticketNumber');
|
||||
$this->ticket = Ticket::getByTicketNumber($ticketNumber);
|
||||
$this->content = Controller::request('content', true);
|
||||
$this->user = Controller::getLoggedUser();
|
||||
|
||||
$ticketAuthor = $this->ticket->authorToArray();
|
||||
$isAuthor = $this->ticket->isAuthor($this->user);
|
||||
$isOwner = $this->ticket->isOwner($this->user);
|
||||
$private = Controller::request('private');
|
||||
$apiKey = APIKey::getDataStore(Controller::request('apiKey'), 'token');
|
||||
|
||||
if(!$this->user->canManageTicket($this->ticket)) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
$this->storeComment();
|
||||
|
||||
if(!$isAuthor && !$private) {
|
||||
$this->sendMail($ticketAuthor);
|
||||
}
|
||||
|
||||
if($this->ticket->owner && !$isOwner) {
|
||||
$this->sendMail([
|
||||
'email' => $this->ticket->owner->email,
|
||||
'name' => $this->ticket->owner->name,
|
||||
'staff' => true
|
||||
]);
|
||||
}
|
||||
|
||||
Log::createLog('COMMENT', $this->ticket->ticketNumber);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
private function storeComment() {
|
||||
$fileUploader = FileUploader::getInstance();
|
||||
$fileUploader->setPermission(FileManager::PERMISSION_TICKET, $this->ticket->ticketNumber);
|
||||
$fileUploader = $this->uploadFile(Controller::isStaffLogged());
|
||||
|
||||
$comment = Ticketevent::getEvent(Ticketevent::COMMENT);
|
||||
$comment->setProperties(array(
|
||||
'content' => $this->replaceWithImagePaths($this->getImagePaths(), $this->content),
|
||||
'file' => ($fileUploader instanceof FileUploader) ? $fileUploader->getFileName() : null,
|
||||
'date' => Date::getCurrentDate(),
|
||||
'private' => (Controller::isStaffLogged() && Controller::request('private')) ? 1 : 0
|
||||
));
|
||||
|
||||
if(Controller::isStaffLogged()) {
|
||||
$this->ticket->unread = !$this->ticket->isAuthor($this->user);
|
||||
$this->ticket->unreadStaff = !$this->ticket->isOwner($this->user);
|
||||
$comment->authorStaff = $this->user;
|
||||
} else {
|
||||
$this->ticket->unreadStaff = true;
|
||||
$comment->authorUser = $this->user;
|
||||
}
|
||||
|
||||
$this->ticket->addEvent($comment);
|
||||
$this->ticket->store();
|
||||
}
|
||||
|
||||
private function sendMail($recipient) {
|
||||
$mailSender = MailSender::getInstance();
|
||||
|
||||
$email = $recipient['email'];
|
||||
$name = $recipient['name'];
|
||||
$isStaff = array_key_exists('staff', $recipient) && $recipient['staff'];
|
||||
|
||||
$url = Setting::getSetting('url')->getValue();
|
||||
|
||||
if(!Controller::isLoginMandatory() && !$isStaff){
|
||||
$url .= '/check-ticket/' . $this->ticket->ticketNumber;
|
||||
$url .= '/' . $email;
|
||||
}
|
||||
$mailSender->setTemplate(MailTemplate::TICKET_RESPONDED, [
|
||||
'to' => $email,
|
||||
'name' => $name,
|
||||
'title' => $this->ticket->title,
|
||||
'ticketNumber' => $this->ticket->ticketNumber,
|
||||
'content' => $this->replaceWithImagePaths($this->getImagePaths(), $this->content),
|
||||
'url' => $url
|
||||
]);
|
||||
|
||||
$mailSender->send();
|
||||
}
|
||||
|
||||
private function getImagePaths() {
|
||||
if(!$this->imagePaths){
|
||||
$this->imagePaths = $this->uploadImages(Controller::isStaffLogged());
|
||||
}
|
||||
|
||||
return $this->imagePaths;
|
||||
}
|
||||
}
|
65
dist/api/controllers/ticket/create-tag.php
vendored
Executable file
65
dist/api/controllers/ticket/create-tag.php
vendored
Executable file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/create-tag Create tag
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Create tag
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path creates a new tag.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} name The new name of the tag.
|
||||
* @apiParam {String} color The new color of the tag.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
* @apiUse TAG_EXISTS
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class CreateTagController extends Controller {
|
||||
const PATH = '/create-tag';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
],
|
||||
'color' => [
|
||||
'validation' => DataValidator::hexRgbColor()->startsWith('#'),
|
||||
'error' => ERRORS::INVALID_COLOR
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$name = Controller::request('name', true);
|
||||
$color = Controller::request('color');
|
||||
|
||||
if (!Tag::getDataStore($name, 'name')->isNull()) {
|
||||
throw new RequestException(ERRORS::TAG_EXISTS);
|
||||
}
|
||||
|
||||
$tagInstance = new Tag();
|
||||
|
||||
$tagInstance->setProperties([
|
||||
'name' => $name,
|
||||
'color' => $color
|
||||
]);
|
||||
$tagInstance->store();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
274
dist/api/controllers/ticket/create.php
vendored
Executable file
274
dist/api/controllers/ticket/create.php
vendored
Executable file
@ -0,0 +1,274 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/create Create ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Create ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path creates a new ticket.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} title Title of the ticket.
|
||||
* @apiParam {String} content Content of the ticket.
|
||||
* @apiParam {Number} departmentId The id of the department of the current ticket.
|
||||
* @apiParam {String} language The language of the ticket.
|
||||
* @apiParam {String} name The name of author of the ticket.
|
||||
* @apiParam {String} email The email of the user who created the ticket.
|
||||
* @apiParam {Number} images The number of images in the content.
|
||||
* @apiParam {String} apiKey apiKey to create tickets and show ticket-number created.
|
||||
* @apiParam image_i The image file of index `i` (mutiple params accepted)
|
||||
* @apiParam file The file you with to upload.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TITLE
|
||||
* @apiUse INVALID_CONTENT
|
||||
* @apiUse INVALID_DEPARTMENT
|
||||
* @apiUse INVALID_LANGUAGE
|
||||
* @apiUse INVALID_CAPTCHA
|
||||
* @apiUse INVALID_EMAIL
|
||||
* @apiUse INVALID_FILE
|
||||
*
|
||||
* @apiSuccess {Object} data Information of the new ticket
|
||||
* @apiSuccess {Number} data.ticketNumber Number of the new ticket
|
||||
*
|
||||
*/
|
||||
|
||||
class CreateController extends Controller {
|
||||
const PATH = '/create';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $title;
|
||||
private $content;
|
||||
private $departmentId;
|
||||
private $language;
|
||||
private $ticketNumber;
|
||||
private $email;
|
||||
private $name;
|
||||
private $apiKey;
|
||||
public function validations() {
|
||||
$validations = [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'title' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TITLE, LengthConfig::MAX_LENGTH_TITLE),
|
||||
'error' => ERRORS::INVALID_TITLE
|
||||
],
|
||||
'content' => [
|
||||
'validation' => DataValidator::content(),
|
||||
'error' => ERRORS::INVALID_CONTENT
|
||||
],
|
||||
'departmentId' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::dataStoreId('department'), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT
|
||||
],
|
||||
'language' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(Language::getSupportedLanguages()), DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_LANGUAGE
|
||||
]
|
||||
]
|
||||
];
|
||||
if (!Controller::isLoginMandatory() && !Controller::isStaffLogged() && !Controller::isUserLogged()) {
|
||||
$validations['permission'] = 'any';
|
||||
$validations['requestData']['captcha'] = [
|
||||
'validation' => DataValidator::captcha(APIKey::TICKET_CREATE_PERMISSION),
|
||||
'error' => ERRORS::INVALID_CAPTCHA
|
||||
];
|
||||
$validations['requestData']['email'] = [
|
||||
'validation' => DataValidator::email(),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
];
|
||||
$validations['requestData']['name'] = [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
];
|
||||
}
|
||||
|
||||
return $validations;
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
|
||||
$session = Session::getInstance();
|
||||
if($session->isTicketSession()) {
|
||||
$session->clearSessionData();
|
||||
}
|
||||
|
||||
$this->title = Controller::request('title', true);
|
||||
$this->content = Controller::request('content', true);
|
||||
$this->departmentId = Controller::request('departmentId');
|
||||
$this->language = Controller::request('language');
|
||||
$this->email = Controller::request('email');
|
||||
$this->name = Controller::request('name');
|
||||
$this->apiKey = APIKey::getDataStore(Controller::request('apiKey'), 'token');
|
||||
|
||||
if(!Controller::isStaffLogged() && Department::getDataStore($this->departmentId)->private) {
|
||||
throw new Exception(ERRORS::INVALID_DEPARTMENT);
|
||||
}
|
||||
|
||||
if(!Staff::getUser($this->email,'email')->isNull() || $this->isEmailInvalid()) {
|
||||
throw new Exception(ERRORS::INVALID_EMAIL);
|
||||
}
|
||||
|
||||
if(!Controller::isLoginMandatory() && !Controller::isStaffLogged() && !Controller::isUserLogged() && User::getUser($this->email, 'email')->isNull()){
|
||||
$this->createNewUser();
|
||||
}
|
||||
|
||||
$this->storeTicket();
|
||||
|
||||
if(!Controller::isLoginMandatory() && !Controller::isUserLogged()) {
|
||||
$this->sendMail();
|
||||
}
|
||||
|
||||
$staffs = Staff::find('send_email_on_new_ticket = 1');
|
||||
foreach ($staffs as $staff) {
|
||||
if($staff->sharedDepartmentList->includesId(Controller::request('departmentId'))) {
|
||||
$this->sendMailStaff($staff->email);
|
||||
}
|
||||
}
|
||||
|
||||
Log::createLog('CREATE_TICKET', $this->ticketNumber);
|
||||
|
||||
if(!$this->apiKey->isNull() && $this->apiKey->shouldReturnTicketNumber){
|
||||
Response::respondSuccess([
|
||||
'ticketNumber' => $this->ticketNumber
|
||||
]);
|
||||
}else{
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
private function isEmailInvalid(){
|
||||
$session = Session::getInstance();
|
||||
$sessionUser = User::getUser($session->getUserId() ,'id');
|
||||
|
||||
return ($session->sessionExists() && $sessionUser && $this->email && !($sessionUser->email == $this->email));
|
||||
}
|
||||
|
||||
private function createNewUser() {
|
||||
|
||||
$signupController = new SignUpController(true);
|
||||
|
||||
Controller::setDataRequester(function ($key) {
|
||||
switch ($key) {
|
||||
case 'email':
|
||||
return $this->email;
|
||||
case 'password':
|
||||
return Hashing::generateRandomToken();
|
||||
case 'name':
|
||||
return $this->name;
|
||||
case 'indirectSignUp' :
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
$signupController->validations();
|
||||
$signupController->handler();
|
||||
}
|
||||
|
||||
private function storeTicket() {
|
||||
$department = Department::getDataStore($this->getCorrectDepartmentId());
|
||||
$author = $this->getAuthor();
|
||||
$this->language = $this->getCorrectLanguage();
|
||||
|
||||
$ticket = new Ticket();
|
||||
|
||||
$fileUploader = FileUploader::getInstance();
|
||||
$fileUploader->setPermission(FileManager::PERMISSION_TICKET, $ticket->generateUniqueTicketNumber());
|
||||
|
||||
$imagePaths = $this->uploadImages(Controller::isStaffLogged());
|
||||
$fileUploader = $this->uploadFile(Controller::isStaffLogged());
|
||||
|
||||
$ticket->setProperties(array(
|
||||
'title' => $this->title,
|
||||
'content' => $this->replaceWithImagePaths($imagePaths, $this->content),
|
||||
'language' => $this->language,
|
||||
'department' => $department,
|
||||
'file' => ($fileUploader instanceof FileUploader) ? $fileUploader->getFileName() : null,
|
||||
'date' => Date::getCurrentDate(),
|
||||
'unread' => false,
|
||||
'unreadStaff' => true,
|
||||
'closed' => false,
|
||||
'authorName' => $this->name,
|
||||
'authorEmail' => $this->email,
|
||||
'totalDepartments' => 0,
|
||||
'totalOwners' => 0
|
||||
));
|
||||
|
||||
$ticket->setAuthor($author);
|
||||
$author->sharedTicketList->add($ticket);
|
||||
|
||||
if(!Controller::isStaffLogged()) {
|
||||
$author->tickets++;
|
||||
|
||||
$this->email = $author->email;
|
||||
$this->name = $author->name;
|
||||
}
|
||||
|
||||
$author->store();
|
||||
$ticket->store();
|
||||
|
||||
$this->ticketNumber = $ticket->ticketNumber;
|
||||
}
|
||||
|
||||
private function getCorrectLanguage() {
|
||||
if($this->language){
|
||||
return $this->language;
|
||||
}else{
|
||||
return Setting::getSetting('language')->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
private function getCorrectDepartmentId(){
|
||||
$defaultDepartmentId = Setting::getSetting('default-department-id')->getValue();
|
||||
$isLocked = Setting::getSetting('default-is-locked')->getValue();
|
||||
$validDepartment = Department::getDataStore($defaultDepartmentId)->id;
|
||||
if (Controller::isStaffLogged()) {
|
||||
if ($this->departmentId) $validDepartment = $this->departmentId;
|
||||
} else {
|
||||
if (!$isLocked && $this->departmentId) $validDepartment = $this->departmentId;
|
||||
}
|
||||
return $validDepartment;
|
||||
}
|
||||
|
||||
private function getAuthor() {
|
||||
if (!Controller::getLoggedUser()->isNull()) {
|
||||
return Controller::getLoggedUser();
|
||||
} else {
|
||||
return User::getUser($this->email, 'email');
|
||||
}
|
||||
}
|
||||
|
||||
private function sendMail() {
|
||||
$mailSender = MailSender::getInstance();
|
||||
|
||||
$mailSender->setTemplate(MailTemplate::TICKET_CREATED, [
|
||||
'to' => $this->email,
|
||||
'name' => $this->name,
|
||||
'ticketNumber' => $this->ticketNumber,
|
||||
'title' => $this->title,
|
||||
'url' => Setting::getSetting('url')->getValue()
|
||||
]);
|
||||
|
||||
$mailSender->send();
|
||||
}
|
||||
|
||||
private function sendMailStaff($email) {
|
||||
$mailSender = MailSender::getInstance();
|
||||
|
||||
$mailSender->setTemplate(MailTemplate::TICKET_CREATED_STAFF, [
|
||||
'to' => $email,
|
||||
'name' => $this->name,
|
||||
'ticketNumber' => $this->ticketNumber,
|
||||
'title' => $this->title
|
||||
]);
|
||||
|
||||
$mailSender->send();
|
||||
}
|
||||
}
|
49
dist/api/controllers/ticket/delete-custom-response.php
vendored
Executable file
49
dist/api/controllers/ticket/delete-custom-response.php
vendored
Executable file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/delete-custom-response Delete custom response
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete custom response
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path deletes a custom response.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {Number} id Id of the custom response to delete.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteCustomResponseController extends Controller {
|
||||
const PATH = '/delete-custom-response';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'id' => [
|
||||
'validation' => DataValidator::dataStoreId('customresponse'),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$customResponse = CustomResponse::getDataStore(Controller::request('id'));
|
||||
$customResponse->delete();
|
||||
|
||||
Log::createLog('DELETE_CUSTOM_RESPONSE', null);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
50
dist/api/controllers/ticket/delete-tag.php
vendored
Executable file
50
dist/api/controllers/ticket/delete-tag.php
vendored
Executable file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/delete-tag Delete a tag
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete tag
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path delete a tag.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} tagId The id of the tag.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TAG
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteTagController extends Controller {
|
||||
const PATH = '/delete-tag';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'tagId' => [
|
||||
'validation' => DataValidator::dataStoreId('tag'),
|
||||
'error' => ERRORS::INVALID_TAG
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
|
||||
$tagInstance = Tag::getDataStore(Controller::request('tagId'));
|
||||
|
||||
$tagInstance->delete();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
69
dist/api/controllers/ticket/delete.php
vendored
Executable file
69
dist/api/controllers/ticket/delete.php
vendored
Executable file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/delete Delete a ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path deletes a ticket.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of the ticket to delete.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class DeleteController extends Controller {
|
||||
const PATH = '/delete';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = Controller::getLoggedUser();
|
||||
$ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
$ticketAuthor = $ticket->authorToArray();
|
||||
|
||||
if($ticket->owner) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if(Controller::isStaffLogged() && $user->level < 3 && ($user->email !== $ticketAuthor['email'])) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if(!Controller::isStaffLogged() && ($user->email !== $ticketAuthor['email'] || $ticketAuthor['staff'])) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if($ticket->author){
|
||||
$ticketAuthor = User::getUser($ticket->authorToArray()['id']);
|
||||
$ticketAuthor->tickets--;
|
||||
$ticketAuthor->store();
|
||||
}
|
||||
|
||||
$ticket->delete();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
100
dist/api/controllers/ticket/edit-comment.php
vendored
Executable file
100
dist/api/controllers/ticket/edit-comment.php
vendored
Executable file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/edit-comment Edit a comment
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit comment
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path edits a comment.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} content The new content of the comment.
|
||||
* @apiParam {Number} ticketEventId The id of the ticket event.
|
||||
* @apiParam {Number} ticketNumber The number of the ticket.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_CONTENT
|
||||
* @apiUse INVALID_TICKET
|
||||
* @apiUse INVALID_TICKET_EVENT
|
||||
* @apiUse TICKET_CONTENT_CANNOT_BE_EDITED
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditCommentController extends Controller {
|
||||
const PATH = '/edit-comment';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'content' => [
|
||||
'validation' => DataValidator::content(),
|
||||
'error' => ERRORS::INVALID_CONTENT
|
||||
],
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validTicketNumber(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = Controller::getLoggedUser();
|
||||
$newcontent = Controller::request('content', true);
|
||||
$ticketNumberLog = null;
|
||||
$ticketEvent = Ticketevent::getTicketEvent(Controller::request('ticketEventId'));
|
||||
$commentAuthor = null;
|
||||
|
||||
if(!$ticketEvent->isNull()) {
|
||||
$ticket = Ticket::getDataStore($ticketEvent->ticketId);
|
||||
$commentAuthor = $ticketEvent->toArray()["author"];
|
||||
} else {
|
||||
$ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
$commentAuthor = $ticket->toArray()["author"];
|
||||
}
|
||||
|
||||
if((!!$user->toArray()["isStaff"] !== !!$commentAuthor["staff"]) || ($user->id !== $commentAuthor["id"])) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if(Controller::isStaffLogged() && !$user->canManageTicket($ticket)) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if(!$ticketEvent->isNull()) {
|
||||
if($ticketEvent->type !== "COMMENT" || $ticket->closed || $ticket->getLatestEventOfType("COMMENT")['id'] !== $ticketEvent->id) {
|
||||
throw new RequestException(ERRORS::INVALID_TICKET_EVENT);
|
||||
}
|
||||
} else if(sizeof($ticket->getEventsOfType("COMMENT"))) {
|
||||
throw new RequestException(ERRORS::TICKET_CONTENT_CANNOT_BE_EDITED);
|
||||
}
|
||||
|
||||
if(!$ticketEvent->isNull()){
|
||||
$ticketNumber = Ticket::getTicket($ticketEvent->ticketId)->ticketNumber;
|
||||
|
||||
$ticketEvent->content = $newcontent;
|
||||
$ticketEvent->editedContent = true;
|
||||
$ticketEvent->store();
|
||||
} else {
|
||||
$ticketNumber = $ticket->ticketNumber;
|
||||
|
||||
$ticket->content = $newcontent;
|
||||
$ticket->editedContent = true;
|
||||
$ticket->store();
|
||||
}
|
||||
|
||||
Log::createLog('EDIT_COMMENT', $ticketNumber);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
76
dist/api/controllers/ticket/edit-custom-response.php
vendored
Executable file
76
dist/api/controllers/ticket/edit-custom-response.php
vendored
Executable file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/edit-custom-response Edit custom response
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit custom response
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path edits a custom response.
|
||||
*
|
||||
* @apiPermission staff2
|
||||
*
|
||||
* @apiParam {Number} id Id of the custom response to edit.
|
||||
* @apiParam {String} content The new content of the custom response. It won't be changed if not defined.
|
||||
* @apiParam {String} language The new language of the custom response. It won't be changed if not defined,
|
||||
* @apiParam {String} name The new name of the custom response. It won't be changed if not defined.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_NAME
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditCustomResponseController extends Controller {
|
||||
const PATH = '/edit-custom-response';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_2',
|
||||
'requestData' => [
|
||||
'id' => [
|
||||
'validation' => DataValidator::dataStoreId('customresponse'),
|
||||
'error' => ERRORS::INVALID_CUSTOM_RESPONSE
|
||||
],
|
||||
'content' => [
|
||||
'validation' => DataValidator::content(),
|
||||
'error' => ERRORS::INVALID_CONTENT
|
||||
],
|
||||
'name' => [
|
||||
'validation' => DataValidator::oneOf(
|
||||
DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
DataValidator::nullType()
|
||||
),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$customResponse = CustomResponse::getDataStore(Controller::request('id'));
|
||||
|
||||
if (Controller::request('content')) {
|
||||
$customResponse->content = Controller::request('content', true);
|
||||
}
|
||||
|
||||
if (Controller::request('language')) {
|
||||
$customResponse->language = Controller::request('language');
|
||||
}
|
||||
|
||||
if (Controller::request('name')) {
|
||||
$customResponse->name = Controller::request('name');
|
||||
}
|
||||
|
||||
$customResponse->store();
|
||||
|
||||
Log::createLog('EDIT_CUSTOM_RESPONSE', null);
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
70
dist/api/controllers/ticket/edit-tag.php
vendored
Executable file
70
dist/api/controllers/ticket/edit-tag.php
vendored
Executable file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/edit-tag Edit tag
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit tag
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path edit tags.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiParam {Number} tagId The id of the tag.
|
||||
* @apiParam {Number} name The new name of the tag.
|
||||
* @apiParam {String} color The new color of the tag.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TAG
|
||||
* @apiUse TAG_EXISTS
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditTagController extends Controller {
|
||||
const PATH = '/edit-tag';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => [
|
||||
'tagId' => [
|
||||
'validation' => DataValidator::dataStoreId('tag'),
|
||||
'error' => ERRORS::INVALID_TAG
|
||||
],
|
||||
'color' => [
|
||||
'validation' => DataValidator::hexRgbColor()->startsWith('#'),
|
||||
'error' => ERRORS::INVALID_COLOR
|
||||
],
|
||||
'name' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||
'error' => ERRORS::INVALID_NAME
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$name = Controller::request('name');
|
||||
$color = Controller::request('color');
|
||||
$tagInstance = Tag::getDataStore(Controller::request('tagId'));
|
||||
|
||||
if($name) $tagInstance->name = $name;
|
||||
if($color) $tagInstance->color = $color;
|
||||
|
||||
$newNameTagInstance = Tag::getDataStore($name, 'name');
|
||||
if (!$newNameTagInstance ->isNull() && $newNameTagInstance->id !== $tagInstance->id) {
|
||||
throw new RequestException(ERRORS::TAG_EXISTS);
|
||||
}
|
||||
|
||||
$tagInstance->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
66
dist/api/controllers/ticket/edit-title.php
vendored
Executable file
66
dist/api/controllers/ticket/edit-title.php
vendored
Executable file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/edit-title Edit title of a ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit title
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path edits the title of a ticket.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} title The new title of the ticket.
|
||||
* @apiParam {Number} ticketNumber The number of the ticket.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TITLE
|
||||
* @apiUse INVALID_TICKET
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditTitleController extends Controller {
|
||||
const PATH = '/edit-title';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'title' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TITLE, LengthConfig::MAX_LENGTH_TITLE),
|
||||
'error' => ERRORS::INVALID_TITLE
|
||||
],
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = Controller::getLoggedUser();
|
||||
$newtitle = Controller::request('title');
|
||||
$ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
|
||||
if(!$user->canManageTicket($ticket)) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
$ticket->title = $newtitle;
|
||||
$ticket->editedTitle = true;
|
||||
$ticket->store();
|
||||
|
||||
$ticketNumber = $ticket->ticketNumber;
|
||||
Log::createLog('EDIT_TITLE', $ticketNumber);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
60
dist/api/controllers/ticket/get-authors.php
vendored
Executable file
60
dist/api/controllers/ticket/get-authors.php
vendored
Executable file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/get-authors Get authors of tickets
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get authors
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path returns all the authors that match with the ids of the list .
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
*
|
||||
* @apiParam {Object[]} authors A array of object {id, isStaff} with id and boolean to get users or staffs.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_LIST
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
class GetAuthorsController extends Controller {
|
||||
const PATH = '/get-authors';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'authors' => [
|
||||
'validation' => DataValidator::ValidAuthorsList(),
|
||||
'error' => ERRORS::INVALID_LIST
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
public function handler() {
|
||||
$dataStores = [];
|
||||
$authors = json_decode(Controller::request('authors'));
|
||||
|
||||
if($authors){
|
||||
foreach ($authors as $author) {
|
||||
$item = [];
|
||||
if($author->isStaff){
|
||||
$item = Staff::getUser($author->id)->toArray(true);
|
||||
}else{
|
||||
$item = User::getUser($author->id)->toArray(true);
|
||||
}
|
||||
array_push($dataStores,$item);
|
||||
}
|
||||
}
|
||||
|
||||
Response::respondSuccess($dataStores);
|
||||
}
|
||||
}
|
39
dist/api/controllers/ticket/get-custom-responses.php
vendored
Executable file
39
dist/api/controllers/ticket/get-custom-responses.php
vendored
Executable file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/get-custom-responses Get custom responses
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get custom responses
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path returns all the custom responses.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[CustomResponse](#api-Data_Structures-ObjectCustomresponse)[]} data List of custom responses.
|
||||
*
|
||||
*/
|
||||
|
||||
class GetCustomResponsesController extends Controller {
|
||||
const PATH = '/get-custom-responses';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$customResponsesList = CustomResponse::getAll();
|
||||
|
||||
Response::respondSuccess($customResponsesList->toArray());
|
||||
}
|
||||
}
|
39
dist/api/controllers/ticket/get-tags.php
vendored
Executable file
39
dist/api/controllers/ticket/get-tags.php
vendored
Executable file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/get-tags Get tags
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get tags
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path returns all the tags.
|
||||
*
|
||||
* @apiPermission staff3
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class GetTagsController extends Controller {
|
||||
const PATH = '/get-tags';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_3',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$tags = Tag::getAll();
|
||||
|
||||
Response::respondSuccess($tags->toArray());
|
||||
}
|
||||
}
|
58
dist/api/controllers/ticket/get.php
vendored
Executable file
58
dist/api/controllers/ticket/get.php
vendored
Executable file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
/**
|
||||
* @api {post} /ticket/get Get ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Get ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path retrieves information about a ticket.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of the ticket.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
*
|
||||
* @apiSuccess {[Ticket](#api-Data_Structures-ObjectTicket)} data Information about the requested ticket.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class TicketGetController extends Controller {
|
||||
const PATH = '/get';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $ticket;
|
||||
|
||||
public function validations() {
|
||||
$session = Session::getInstance();
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::NO_PERMISSION
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
|
||||
if ($this->shouldDenyPermission()) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
} else {
|
||||
Response::respondSuccess($this->ticket->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
private function shouldDenyPermission() {
|
||||
$user = Controller::getLoggedUser();
|
||||
return !$user->canManageTicket($this->ticket);
|
||||
}
|
||||
}
|
86
dist/api/controllers/ticket/re-open.php
vendored
Executable file
86
dist/api/controllers/ticket/re-open.php
vendored
Executable file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/re-open Reopen ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Reopen ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path reopens a closed ticket.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} ticketNumber Number of the ticket to be reopened.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class ReOpenController extends Controller {
|
||||
const PATH = '/re-open';
|
||||
const METHOD = 'POST';
|
||||
|
||||
private $ticket;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
if (!$user->canManageTicket($this->ticket)) throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
|
||||
$this->markAsUnread();
|
||||
$this->addReopenEvent();
|
||||
|
||||
if ($this->ticket->closed) {
|
||||
$this->ticket->reopened = true;
|
||||
}
|
||||
$this->ticket->closed = false;
|
||||
|
||||
$this->ticket->store();
|
||||
|
||||
Log::createLog('RE_OPEN', $this->ticket->ticketNumber);
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
private function markAsUnread() {
|
||||
if(Controller::isStaffLogged()) {
|
||||
$this->ticket->unread = true;
|
||||
} else {
|
||||
$this->ticket->unreadStaff = true;
|
||||
}
|
||||
}
|
||||
|
||||
private function addReopenEvent() {
|
||||
$event = Ticketevent::getEvent(Ticketevent::RE_OPEN);
|
||||
$event->setProperties(array(
|
||||
'date' => Date::getCurrentDate()
|
||||
));
|
||||
|
||||
if(Controller::isStaffLogged()) {
|
||||
$event->authorStaff = Controller::getLoggedUser();
|
||||
} else {
|
||||
$event->authorUser = Controller::getLoggedUser();
|
||||
}
|
||||
|
||||
$this->ticket->addEvent($event);
|
||||
}
|
||||
}
|
63
dist/api/controllers/ticket/remove-tag.php
vendored
Executable file
63
dist/api/controllers/ticket/remove-tag.php
vendored
Executable file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/remove-tag Remove tag
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Remove tag
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path removes a tag from a ticket.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} ticketNumber The number of the ticket which the tag is going to be removed.
|
||||
* @apiParam {String} tagId The id of the tag to be removed.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
* @apiUse INVALID_TAG
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class RemoveTagController extends Controller {
|
||||
const PATH = '/remove-tag';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
],
|
||||
'tagId' => [
|
||||
'validation' => DataValidator::dataStoreId('tag'),
|
||||
'error' => ERRORS::INVALID_TAG
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$tagId = Controller::request('tagId');
|
||||
$tag = Tag::getDataStore($tagId);
|
||||
$ticket = Ticket::getByTicketNumber(Controller::request('ticketNumber'));
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
if (!$user->canManageTicket($ticket)) throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
|
||||
if (!$ticket->sharedTagList->includesId($tagId)) throw new RequestException(ERRORS::INVALID_TAG);
|
||||
|
||||
$ticket->sharedTagList->remove($tag);
|
||||
$ticket->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
122
dist/api/controllers/ticket/search-authors.php
vendored
Executable file
122
dist/api/controllers/ticket/search-authors.php
vendored
Executable file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/search-authors search authors of tickets
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Search authors
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path returns all the authors that match with the query.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
*
|
||||
* @apiParam {String} query A string to find into a ticket to make a custom search.
|
||||
* @apiParam {Object[]} blackList A array of objects {id, isStaff} with id and boolean to eliminate the authors of the new list.
|
||||
* @apiParam {Boolean} searchUsers A boolean that determinates if the search is for users or not
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_QUERY
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class SearchAuthorsController extends Controller {
|
||||
const PATH = '/search-authors';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'query' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::stringType(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_QUERY
|
||||
],
|
||||
'blackList' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validAuthorsBlackList(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_BLACK_LIST
|
||||
],
|
||||
'searchUsers' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(['0','1']),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_USER_SEARCH_OPTION
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$query = Controller::request('query');
|
||||
$searchUser = Controller::request('searchUsers') ? Controller::request('searchUsers') : 0;
|
||||
|
||||
if(!$searchUser){
|
||||
$sqlQuery = $this->generateAuthorsIdQuery($query);
|
||||
}else{
|
||||
$sqlQuery = $this->generateUsersIdQuery($query);
|
||||
}
|
||||
|
||||
$dataStoresMatch = RedBean::getAll($sqlQuery, [':query' => "%" .$query . "%",':queryAtBeginning' => $query . "%"] );
|
||||
|
||||
$list = [];
|
||||
foreach($dataStoresMatch as $dataStoreMatch) {
|
||||
if(!$searchUser && $dataStoreMatch['level'] >=1 && $dataStoreMatch['level'] <= 3){
|
||||
$dataStore = Staff::getDataStore($dataStoreMatch['id']*1);
|
||||
} else {
|
||||
$dataStore = User::getDataStore($dataStoreMatch['id']*1);
|
||||
}
|
||||
array_push($list, $dataStore->toArray(true));
|
||||
}
|
||||
Response::respondSuccess([
|
||||
'authors' => $list
|
||||
]);
|
||||
}
|
||||
public function generateAuthorsIdQuery($query) {
|
||||
if ($query){
|
||||
return "SELECT id,name, level FROM staff WHERE name LIKE :query " . $this->generateStaffBlackListQuery() . " UNION SELECT id,name,signup_date FROM user WHERE name LIKE :query " . $this->generateUserBlackListQuery() . " ORDER BY CASE WHEN (name LIKE :queryAtBeginning) THEN 1 ELSE 2 END ASC LIMIT 10";
|
||||
} else {
|
||||
return "SELECT id,name, level FROM staff WHERE 1=1 ". $this->generateStaffBlackListQuery() . " UNION SELECT id,name,signup_date FROM user WHERE 1=1". $this->generateUserBlackListQuery() ." ORDER BY id LIMIT 10";
|
||||
}
|
||||
}
|
||||
public function generateUsersIdQuery($query) {
|
||||
if ($query){
|
||||
return "SELECT id FROM user WHERE name LIKE :query " . $this->generateUserBlackListQuery() . " ORDER BY CASE WHEN (name LIKE :queryAtBeginning) THEN 1 ELSE 2 END ASC LIMIT 10";
|
||||
} else {
|
||||
return "SELECT id FROM user WHERE 1=1 ". $this->generateUserBlackListQuery() ." ORDER BY id LIMIT 10";
|
||||
}
|
||||
}
|
||||
|
||||
public function generateStaffBlackListQuery(){
|
||||
$StaffBlackList = $this->getBlackListFiltered();
|
||||
return $this->generateBlackListQuery($StaffBlackList);
|
||||
}
|
||||
|
||||
public function generateUserBlackListQuery(){
|
||||
$UserBlackList = $this->getBlackListFiltered(0);
|
||||
return $this->generateBlackListQuery($UserBlackList);
|
||||
}
|
||||
|
||||
public function generateBlackListQuery($idList){
|
||||
$text = "";
|
||||
foreach ($idList as $id) {
|
||||
$text .= " AND id != " . $id;
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
public function getBlackListFiltered($staff = 1){
|
||||
$blackList = json_decode(Controller::request('blackList'));
|
||||
$idList = [];
|
||||
if($blackList){
|
||||
foreach ($blackList as $item) {
|
||||
if($staff == $item->isStaff) array_push($idList, $item->id);
|
||||
}
|
||||
}
|
||||
return $idList;
|
||||
}
|
||||
}
|
374
dist/api/controllers/ticket/search.php
vendored
Executable file
374
dist/api/controllers/ticket/search.php
vendored
Executable file
@ -0,0 +1,374 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/search Search tickets
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Search ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path search specific tickets.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {Number[]} tags The ids of the tags to make a custom search.
|
||||
* @apiParam {Number} closed The status of closed 1 or 0 to make a custom search.
|
||||
* @apiParam {Number} unreadStaff The status of unread_staff 1 or 0 to make a custom search.
|
||||
* @apiParam {Number[]} dateRange The numbers of the range of date to make a custom search.
|
||||
* @apiParam {Number[]} departments The ids of the departments to make a custom search.
|
||||
* @apiParam {Object[]} authors A object {id,staff} with id and boolean to make a custom search.
|
||||
* @apiParam {Number} assigned The status of assigned 1 or 0 to make a custom search.
|
||||
* @apiParam {String} query A string to find into a ticket to make a custom search.
|
||||
* @apiParam {Number} page The number of the page of the tickets.
|
||||
* @apiParam {Object} orderBy A object {value, asc}with string and boolean to make a especific order of the search.
|
||||
* @apiParam {Number[]} owners The ids of the owners to make a custom search.
|
||||
* @apiParam {Boolean} supervisor Boolean to deteminate if a super-user is making the call.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TAG_FILTER
|
||||
* @apiUse INVALID_CLOSED_FILTER
|
||||
* @apiUse INVALID_UNREAD_STAFF_FILTER
|
||||
* @apiUse INVALID_DATE_RANGE_FILTER
|
||||
* @apiUse INVALID_DEPARTMENT_FILTER
|
||||
* @apiUse INVALID_AUTHOR_FILTER
|
||||
* @apiUse INVALID_ASSIGNED_FILTER
|
||||
* @apiUse INVALID_ORDER_BY
|
||||
* @apiUse INVALID_PAGE
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
class SearchController extends Controller {
|
||||
const PATH = '/search';
|
||||
const METHOD = 'POST';
|
||||
private $ignoreDeparmentFilter;
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'page' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::numeric()->positive(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_PAGE
|
||||
],
|
||||
'tags' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validTagsId(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_TAG_FILTER
|
||||
],
|
||||
'closed' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(['0','1']),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_CLOSED_FILTER
|
||||
],
|
||||
'unreadStaff' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(['0','1']),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_UNREAD_STAFF_FILTER
|
||||
],
|
||||
'dateRange' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validDateRange(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_DATE_RANGE_FILTER
|
||||
],
|
||||
'departments' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validDepartmentsId(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_DEPARTMENT_FILTER
|
||||
],
|
||||
'authors' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validAuthorsId(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_AUTHOR_FILTER
|
||||
],
|
||||
'owners' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validOwnersId(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_OWNER_FILTER
|
||||
],
|
||||
'assigned' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::in(['0','1']),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_ASSIGNED_FILTER
|
||||
],
|
||||
'query' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::notBlank(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_QUERY_FILTER
|
||||
],
|
||||
'orderBy' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::validOrderBy(),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_ORDER_BY
|
||||
],
|
||||
'pageSize' => [
|
||||
'validation' => DataValidator::oneOf(DataValidator::intVal()->between(5, 50),DataValidator::nullType()),
|
||||
'error' => ERRORS::INVALID_PAGE_SIZE
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$this->ignoreDeparmentFilter = (bool)Controller::request('supervisor');
|
||||
|
||||
$allowedDepartmentsId = [];
|
||||
foreach (Controller::getLoggedUser()->sharedDepartmentList->toArray() as $department) {
|
||||
array_push($allowedDepartmentsId,$department['id']);
|
||||
}
|
||||
|
||||
$inputs = [
|
||||
'closed' => Controller::request('closed'),
|
||||
'tags' => json_decode(Controller::request('tags')),
|
||||
'unreadStaff' => Controller::request('unreadStaff'),
|
||||
'dateRange' => json_decode(Controller::request('dateRange')),
|
||||
'departments' => json_decode(Controller::request('departments')),
|
||||
'authors' => json_decode(Controller::request('authors'),true),
|
||||
'owners' => json_decode(Controller::request('owners')),
|
||||
'assigned' => Controller::request('assigned'),
|
||||
'query' => Controller::request('query'),
|
||||
'orderBy' => json_decode(Controller::request('orderBy'),true),
|
||||
'page' => Controller::request('page'),
|
||||
'allowedDepartments' => $allowedDepartmentsId,
|
||||
'staffId' => Controller::getLoggedUser()->id,
|
||||
'pageSize' => Controller::request('pageSize') ? Controller::request('pageSize') : 10
|
||||
];
|
||||
$query = $this->getSQLQuery($inputs);
|
||||
$queryWithOrder = $this->getSQLQueryWithOrder($inputs, $query);
|
||||
$totalCount = RedBean::getAll("SELECT COUNT(*) FROM (SELECT COUNT(*) " . $query . " ) AS T2", [':query' => "%" . $inputs['query'] . "%", ':queryAtBeginning' => $inputs['query'] . "%" ])[0]['COUNT(*)'];
|
||||
$ticketIdList = RedBean::getAll($queryWithOrder, [':query' => "%" . $inputs['query'] . "%", ':queryAtBeginning' => $inputs['query'] . "%"]);
|
||||
$ticketList = [];
|
||||
foreach ($ticketIdList as $item) {
|
||||
$ticket = Ticket::getDataStore($item['id']);
|
||||
array_push($ticketList, $ticket->toArray());
|
||||
}
|
||||
Response::respondSuccess([
|
||||
'tickets' => $ticketList,
|
||||
'pages' => ceil($totalCount / $inputs['pageSize']),
|
||||
'page' => $inputs['page'] ? ($inputs['page']*1) : 1
|
||||
]);
|
||||
}
|
||||
|
||||
public function getSQLQuery($inputs) {
|
||||
$taglistQuery = " LEFT JOIN tag_ticket ON tag_ticket.ticket_id = ticket.id";
|
||||
$ticketeventlistQuery = " LEFT JOIN ticketevent ON ticketevent.ticket_id = ticket.id";
|
||||
|
||||
$query = "FROM (ticket" . $taglistQuery . $ticketeventlistQuery .")";
|
||||
$filters = "";
|
||||
$this->setQueryFilters($inputs, $filters);
|
||||
$query .= $filters . " GROUP BY ticket.id";
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function getSQLQueryWithOrder($inputs, $query) {
|
||||
$order = "";
|
||||
$query = "SELECT ticket.id " . $query;
|
||||
|
||||
$this->setQueryOrder($inputs, $order);
|
||||
$inputs['page'] ? $page = $inputs['page'] : $page = 1 ;
|
||||
$query .= $order . ' LIMIT ' . $inputs['pageSize'] . ' OFFSET ' . ($page-1)*10;
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
//FILTER
|
||||
private function setQueryFilters($inputs, &$filters){
|
||||
if(array_key_exists('tags',$inputs)) $this->setTagFilter($inputs['tags'], $filters);
|
||||
if(array_key_exists('closed',$inputs)) $this->setClosedFilter($inputs['closed'], $filters);
|
||||
if(array_key_exists('assigned',$inputs)) $this->setAssignedFilter($inputs['assigned'], $filters);
|
||||
if(array_key_exists('unreadStaff',$inputs)) {
|
||||
$this->setSeenFilter($inputs['unreadStaff'], $filters);
|
||||
}
|
||||
if(array_key_exists('dateRange',$inputs)) $this->setDateFilter($inputs['dateRange'], $filters);
|
||||
if(array_key_exists('departments',$inputs) && array_key_exists('allowedDepartments',$inputs) && array_key_exists('staffId',$inputs)){
|
||||
if(!$this->ignoreDeparmentFilter) $this->setDepartmentFilter($inputs['departments'],$inputs['allowedDepartments'], $inputs['staffId'], $filters);
|
||||
}
|
||||
if(array_key_exists('authors',$inputs)) $this->setAuthorFilter($inputs['authors'], $filters);
|
||||
if(array_key_exists('owners',$inputs)) $this->setOwnerFilter($inputs['owners'], $filters);
|
||||
if(array_key_exists('query',$inputs)) $this->setStringFilter($inputs['query'], $filters);
|
||||
if($filters != "") $filters = " WHERE " . $filters;
|
||||
}
|
||||
|
||||
private function setTagFilter($tagList, &$filters){
|
||||
if($tagList){
|
||||
$filters != "" ? $filters .= " and " : null;
|
||||
|
||||
foreach($tagList as $key => $tag) {
|
||||
|
||||
$key == 0 ? $filters .= " ( " : null;
|
||||
($key != 0 && $key != sizeof($tagList)) ? $filters .= " or " : null;
|
||||
|
||||
$filters .= "tag_ticket.tag_id = " . $tag ;
|
||||
}
|
||||
$filters .= ")";
|
||||
}
|
||||
}
|
||||
public function setClosedFilter($closed, &$filters){
|
||||
if ($closed !== null) {
|
||||
if ($filters != "") $filters .= " and ";
|
||||
$filters .= "ticket.closed = " . $closed ;
|
||||
}
|
||||
}
|
||||
private function setSeenFilter($unreadStaff, &$filters){
|
||||
if ($unreadStaff !== null) {
|
||||
if ($filters != "") $filters .= " and ";
|
||||
$filters .= "ticket.unread_staff = " . $unreadStaff;
|
||||
}
|
||||
}
|
||||
|
||||
private function setDateFilter($dateRange, &$filters){
|
||||
if ($dateRange !== null) {
|
||||
if ($filters != "") $filters .= " and ";
|
||||
|
||||
foreach($dateRange as $key => $date) {
|
||||
$key == 0 ? ($filters .= "(ticket.date >= " . $date ): ($filters .= " and ticket.date <= " . $date . ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setDepartmentFilter($requestedDepartments,$myDepartments, $idStaff, &$filters){
|
||||
if (!$requestedDepartments) $requestedDepartments = [];
|
||||
|
||||
$requestedOwnedDepartments = $this->getRequestedOwnedDepartments($requestedDepartments, $myDepartments);
|
||||
$requestedNotOwnedDepartments = $this->getRequestedNotOwnedDepartments($requestedDepartments, $myDepartments);
|
||||
$first = TRUE;
|
||||
if(!$requestedOwnedDepartments && !$requestedNotOwnedDepartments && !!$myDepartments){
|
||||
if ($filters != "") $filters .= " and ";
|
||||
foreach($myDepartments as $department) {
|
||||
if($first){
|
||||
$filters .= "(ticket.author_staff_id = " . $idStaff . " or ";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
$filters .= "ticket.department_id = " . $department;
|
||||
}
|
||||
$filters .= ")";
|
||||
}
|
||||
|
||||
if($requestedOwnedDepartments){
|
||||
foreach($requestedOwnedDepartments as $department) {
|
||||
if($first){
|
||||
$filters .= " ( ";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
$filters .= "ticket.department_id = " . $department;
|
||||
}
|
||||
}
|
||||
|
||||
if($requestedNotOwnedDepartments){
|
||||
if($requestedOwnedDepartments) $filters .= " or ";
|
||||
$filters .= "(ticket.author_staff_id = " . $idStaff . " and ";
|
||||
$first = TRUE;
|
||||
foreach($requestedNotOwnedDepartments as $department) {
|
||||
if($first){
|
||||
$filters .= " ( ";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
$filters .= "ticket.department_id = " . $department;
|
||||
}
|
||||
$filters .= "))";
|
||||
}
|
||||
if($requestedOwnedDepartments) $filters .= " )";
|
||||
}
|
||||
|
||||
private function setAuthorFilter($authors, &$filters){
|
||||
if($authors){
|
||||
$first = TRUE;
|
||||
if ($filters != "") $filters .= " and ";
|
||||
|
||||
foreach($authors as $author){
|
||||
|
||||
if($first){
|
||||
$filters .= " ( ";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
|
||||
if($author['isStaff']){
|
||||
$filters .= "ticket.author_staff_id = " . $author['id'];
|
||||
} else {
|
||||
$filters .= "ticket.author_id = " . $author['id'];
|
||||
}
|
||||
}
|
||||
$filters .= ")";
|
||||
}
|
||||
}
|
||||
|
||||
private function setOwnerFilter($owners, &$filters){
|
||||
if($owners){
|
||||
$first = TRUE;
|
||||
if ($filters != "") $filters .= " and ";
|
||||
|
||||
foreach($owners as $owner){
|
||||
|
||||
if($first){
|
||||
$filters .= "(";
|
||||
$first = FALSE;
|
||||
} else {
|
||||
$filters .= " or ";
|
||||
}
|
||||
$filters .= "ticket.owner_id = " . $owner;
|
||||
}
|
||||
|
||||
$filters .= ")";
|
||||
}
|
||||
}
|
||||
|
||||
private function setAssignedFilter($assigned, &$filters){
|
||||
if($assigned !== null){
|
||||
if ($filters != "") $filters .= " and ";
|
||||
$key = "";
|
||||
$assigned == 0 ? $key = "IS NULL" : $key = "IS NOT NULL";
|
||||
$filters .= "ticket.owner_id " . $key;
|
||||
}
|
||||
}
|
||||
|
||||
private function setStringFilter($search, &$filters){
|
||||
if($search !== null){
|
||||
if ($filters != "") $filters .= " and ";
|
||||
$ticketevent = " or (ticketevent.type = 'COMMENT' and ticketevent.content LIKE :query)";
|
||||
$filters .= " (ticket.title LIKE :query or ticket.content LIKE :query or ticket.ticket_number LIKE :query". $ticketevent ." )";
|
||||
};
|
||||
}
|
||||
|
||||
private function getRequestedOwnedDepartments($requestedDepartments, $myDepartments){
|
||||
$requestedOwnedDepartments = [];
|
||||
$requestedOwnedDepartments = array_values(array_unique(array_intersect($requestedDepartments, $myDepartments)));
|
||||
|
||||
return $requestedOwnedDepartments;
|
||||
}
|
||||
|
||||
private function getRequestedNotOwnedDepartments($requestedDepartments, $myDepartments){
|
||||
$requestedNotOwnedDepartments = [];
|
||||
$requestedOwnedDepartments = [];
|
||||
$requestedOwnedDepartments = array_values(array_unique(array_intersect($requestedDepartments, $myDepartments)));
|
||||
$requestedNotOwnedDepartments = array_values(array_diff($requestedDepartments, $requestedOwnedDepartments));
|
||||
|
||||
return $requestedNotOwnedDepartments;
|
||||
}
|
||||
|
||||
//ORDER
|
||||
private function setQueryOrder($inputs, &$order){
|
||||
$order = " ORDER BY ";
|
||||
if(array_key_exists('query',$inputs)) $this->setStringOrder($inputs['query'], $order);
|
||||
if(array_key_exists('orderBy',$inputs)) $this->setEspecificOrder($inputs['orderBy'], $order);
|
||||
$order .= "ticket.closed asc, ticket.owner_id asc, ticket.unread_staff asc, ticket.date desc, ticket.id desc";
|
||||
}
|
||||
private function setEspecificOrder($orderBy, &$order){
|
||||
if($orderBy !== null){
|
||||
$orientation = ($orderBy['asc'] ? " asc" : " desc" );
|
||||
$order .= "ticket." . $orderBy['value'] . $orientation . ",";
|
||||
};
|
||||
}
|
||||
private function setStringOrder($querysearch, &$order){
|
||||
if($querysearch !== null){
|
||||
$ticketeventOrder = " WHEN (ticketevent.content LIKE :query) THEN 5 ";
|
||||
$order .= "CASE WHEN (ticket.ticket_number LIKE :query) THEN 1 WHEN (ticket.title LIKE :queryAtBeginning) THEN 2 WHEN (ticket.title LIKE :query) THEN 3 WHEN ( ticket.content LIKE :query) THEN 4 " . $ticketeventOrder ."END asc, ";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
62
dist/api/controllers/ticket/seen.php
vendored
Executable file
62
dist/api/controllers/ticket/seen.php
vendored
Executable file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /ticket/seen See ticket
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName See ticket
|
||||
*
|
||||
* @apiGroup Ticket
|
||||
*
|
||||
* @apiDescription This path sets "unread" value to false, so it does not appear highlighted.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {Number} ticketNumber Number of the ticket.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_TICKET
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class SeenController extends Controller {
|
||||
const PATH = '/seen';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'ticketNumber' => [
|
||||
'validation' => DataValidator::validTicketNumber(),
|
||||
'error' => ERRORS::INVALID_TICKET
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$ticketnumber = Controller::request('ticketNumber');
|
||||
$user = Controller::getLoggedUser();
|
||||
$ticket = Ticket::getByTicketNumber($ticketnumber);
|
||||
|
||||
if(!$user->canManageTicket($ticket) && !$ticket->isAuthor($user)) {
|
||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||
}
|
||||
|
||||
if ($ticket->isOwner($user)) {
|
||||
$ticket->unreadStaff = false;
|
||||
}
|
||||
if ($ticket->isAuthor($user)) {
|
||||
$ticket->unread = false;
|
||||
}
|
||||
|
||||
$ticket->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
31
dist/api/controllers/user.php
vendored
Executable file
31
dist/api/controllers/user.php
vendored
Executable file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
$userControllers = new ControllerGroup();
|
||||
$userControllers->setGroupPath('/user');
|
||||
|
||||
$userControllers->addController(new LoginController);
|
||||
$userControllers->addController(new SignUpController);
|
||||
$userControllers->addController(new InviteUserController);
|
||||
$userControllers->addController(new LogoutController);
|
||||
$userControllers->addController(new CheckSessionController);
|
||||
$userControllers->addController(new SendRecoverPasswordController);
|
||||
$userControllers->addController(new RecoverPasswordController);
|
||||
$userControllers->addController(new EditPassword);
|
||||
$userControllers->addController(new EditEmail);
|
||||
$userControllers->addController(new GetUserController);
|
||||
$userControllers->addController(new GetUsersController);
|
||||
$userControllers->addController(new GetUserByIdController);
|
||||
$userControllers->addController(new DeleteUserController);
|
||||
$userControllers->addController(new BanUserController);
|
||||
$userControllers->addController(new UnBanUserController);
|
||||
$userControllers->addController(new ListBanUserController);
|
||||
$userControllers->addController(new VerifyController);
|
||||
$userControllers->addController(new EnableUserController);
|
||||
$userControllers->addController(new DisableUserController);
|
||||
$userControllers->addController(new EditCustomFieldsController);
|
||||
$userControllers->addController(new EditSupervisedListController);
|
||||
$userControllers->addController(new GetSupervisedTicketController);
|
||||
$userControllers->addController(new ResendEmailTokenController);
|
||||
|
||||
$userControllers->addController(new ResendInviteUserController);
|
||||
|
||||
$userControllers->finalize();
|
61
dist/api/controllers/user/ban.php
vendored
Executable file
61
dist/api/controllers/user/ban.php
vendored
Executable file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /user/ban Ban email
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Ban email
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path takes an email and adds it to the ban list.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {String} email Email of user to ban.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_EMAIL
|
||||
* @apiUse ALREADY_BANNED
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
class BanUserController extends Controller {
|
||||
const PATH = '/ban';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'email' => [
|
||||
'validation' => DataValidator::email(),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$email = Controller::request('email');
|
||||
|
||||
$banRow = Ban::getDataStore($email,'email');
|
||||
if($banRow->isNull()) {
|
||||
$ban = new Ban();
|
||||
|
||||
$ban->setProperties(array(
|
||||
'email' => $email
|
||||
));
|
||||
|
||||
$ban->store();
|
||||
|
||||
Log::createLog('BAN_USER', $email);
|
||||
|
||||
Response::respondSuccess();
|
||||
} else {
|
||||
throw new RequestException(ERRORS::ALREADY_BANNED);
|
||||
}
|
||||
}
|
||||
}
|
38
dist/api/controllers/user/check-session.php
vendored
Executable file
38
dist/api/controllers/user/check-session.php
vendored
Executable file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @api {post} /user/check-session Check session
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Check session
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path checks if the session exists.
|
||||
*
|
||||
* @apiPermission any
|
||||
*
|
||||
* @apiSuccess {Object} data Information about the session.
|
||||
* @apiSuccess {Boolean} data.sessionActive Indicates if the session is active.
|
||||
*
|
||||
*/
|
||||
|
||||
class CheckSessionController extends Controller {
|
||||
const PATH = '/check-session';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'any',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$session = Session::getInstance();
|
||||
|
||||
Response::respondSuccess([
|
||||
'sessionActive' => $session->sessionExists()
|
||||
]);
|
||||
}
|
||||
}
|
60
dist/api/controllers/user/delete.php
vendored
Executable file
60
dist/api/controllers/user/delete.php
vendored
Executable file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
use RedBeanPHP\Facade as RedBean;
|
||||
|
||||
/**
|
||||
* @api {post} /user/delete Delete user
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Delete user
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path receives an user id and deletes the user.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number} userId The id of the user to delete.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_USER
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
DataValidator::with('CustomValidations', true);
|
||||
|
||||
class DeleteUserController extends Controller {
|
||||
const PATH = '/delete';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'userId' => [
|
||||
'validation' => DataValidator::dataStoreId('user'),
|
||||
'error' => ERRORS::INVALID_USER
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
|
||||
$userId = Controller::request('userId');
|
||||
$user = User::getDataStore($userId);
|
||||
|
||||
Log::createLog('DELETE_USER', $user->name);
|
||||
RedBean::exec('DELETE FROM log WHERE author_user_id = ?', [$userId]);
|
||||
|
||||
foreach($user->sharedTicketList as $ticket) {
|
||||
$ticket->delete();
|
||||
}
|
||||
|
||||
$user->delete();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
52
dist/api/controllers/user/disable.php
vendored
Executable file
52
dist/api/controllers/user/disable.php
vendored
Executable file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /user/disable Ban email
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Disable User
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path takes an user id and disabled access for it
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {String} userId Id of the user to disable
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_USER
|
||||
* @apiUse ALREADY_DISABLED
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
class DisableUserController extends Controller {
|
||||
const PATH = '/disable';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'userId' => [
|
||||
'validation' => DataValidator::dataStoreId('user'),
|
||||
'error' => ERRORS::INVALID_USER
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = User::getDataStore(Controller::request('userId'));
|
||||
if($user->disabled) {
|
||||
throw new RequestException(ERRORS::ALREADY_DISABLED);
|
||||
}
|
||||
|
||||
$user->disabled = 1;
|
||||
$user->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
55
dist/api/controllers/user/edit-custom-fields.php
vendored
Executable file
55
dist/api/controllers/user/edit-custom-fields.php
vendored
Executable file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /user/edit-custom-fields Edit custom field values
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit custom field values
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path is for editing the custom fields of a user.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} userId Id of the user if it is not the one logged. Optional.
|
||||
* @apiParam {String} customfield_ Custom field values for this user.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_CUSTOM_FIELD_OPTION
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditCustomFieldsController extends Controller {
|
||||
const PATH = '/edit-custom-fields';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => []
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$userId = Controller::request('userId') * 1;
|
||||
$user = Controller::getLoggedUser();
|
||||
|
||||
if($userId && Controller::isStaffLogged(2)) {
|
||||
$user = User::getDataStore($userId);
|
||||
|
||||
if($user->isNull())
|
||||
throw new RequestException(ERRORS::INVALID_USER);
|
||||
}
|
||||
|
||||
$user->setProperties([
|
||||
'xownCustomfieldvalueList' => $this->getCustomFieldValues()
|
||||
]);
|
||||
|
||||
$user->store();
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
76
dist/api/controllers/user/edit-email.php
vendored
Executable file
76
dist/api/controllers/user/edit-email.php
vendored
Executable file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /user/edit-email Edit email
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit email
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path changes the email of an user.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} newEmail The new email that the user wants to change.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_EMAIL
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditEmail extends Controller{
|
||||
const PATH = '/edit-email';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'newEmail' => [
|
||||
'validation' => DataValidator::email(),
|
||||
'error' => ERRORS::INVALID_EMAIL
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$newEmail = Controller::request('newEmail');
|
||||
$user = Controller::getLoggedUser();
|
||||
$oldEmail = $user->email;
|
||||
|
||||
$this->verifyEmail($newEmail, $user);
|
||||
|
||||
$user->email = $newEmail;
|
||||
|
||||
$user->store();
|
||||
|
||||
$mailSender = MailSender::getInstance();
|
||||
$mailSender->setTemplate('USER_EMAIL', [
|
||||
'to'=>$oldEmail,
|
||||
'newemail'=>$user->email,
|
||||
'name'=>$user->name
|
||||
]);
|
||||
$mailSender->send();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
private function verifyEmail($email, $logedUser){
|
||||
|
||||
$staff = Staff::getDataStore($email,'email');
|
||||
$user = User::getDataStore($email,'email');
|
||||
|
||||
if($user->email == $email && $logedUser->email != $email){
|
||||
throw new RequestException(ERRORS::INVALID_EMAIL);
|
||||
}
|
||||
|
||||
if($staff->email == $email){
|
||||
throw new RequestException(ERRORS::INVALID_EMAIL);
|
||||
}
|
||||
}
|
||||
}
|
64
dist/api/controllers/user/edit-password.php
vendored
Executable file
64
dist/api/controllers/user/edit-password.php
vendored
Executable file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /user/edit-password Edit password
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit password
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path edits the password of an user.
|
||||
*
|
||||
* @apiPermission user
|
||||
*
|
||||
* @apiParam {String} newPassword The new password that the user wants to change.
|
||||
* @apiParam {String} oldPassword The actual password of the user.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_PASSWORD
|
||||
* @apiUse INVALID_OLD_PASSWORD
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditPassword extends Controller {
|
||||
const PATH = '/edit-password';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'user',
|
||||
'requestData' => [
|
||||
'newPassword' => [
|
||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_PASSWORD, LengthConfig::MAX_LENGTH_PASSWORD),
|
||||
'error' => ERRORS::INVALID_PASSWORD
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$oldPassword = Controller::request('oldPassword');
|
||||
$newPassword = Controller::request('newPassword');
|
||||
$user = Controller::getLoggedUser() ;
|
||||
|
||||
if (Hashing::verifyPassword($oldPassword, $user->password)) {
|
||||
$user->password = Hashing::hashPassword($newPassword);
|
||||
$user->store();
|
||||
|
||||
$mailSender = MailSender::getInstance();
|
||||
$mailSender->setTemplate('USER_PASSWORD', [
|
||||
'to'=>$user->email,
|
||||
'name'=>$user->name
|
||||
]);
|
||||
$mailSender->send();
|
||||
|
||||
Response::respondSuccess();
|
||||
} else{
|
||||
throw new RequestException(ERRORS::INVALID_OLD_PASSWORD);
|
||||
}
|
||||
}
|
||||
}
|
81
dist/api/controllers/user/edit-supervised-list.php
vendored
Executable file
81
dist/api/controllers/user/edit-supervised-list.php
vendored
Executable file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /user/edit-supervised-list Edit user list
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Edit user list
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path edits the user list of a user.
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {Number[]} userIdList The ids of the users.
|
||||
* @apiParam {Number} userId Id of the supervisor user.
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_LIST
|
||||
* @apiUse INVALID_USER
|
||||
* @apiUse SUPERVISOR_CAN_NOT_SUPERVISE_HIMSELF
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
|
||||
class EditSupervisedListController extends Controller {
|
||||
const PATH = '/edit-supervised-list';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'userIdList' => [
|
||||
'validation' => DataValidator::validUsersId(),
|
||||
'error' => ERRORS::INVALID_LIST
|
||||
],
|
||||
'userId' => [
|
||||
'validation' => DataValidator::dataStoreId('user'),
|
||||
'error' => ERRORS::INVALID_USER
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$userIdList = $this->getUserIdListCleared();
|
||||
$superUser = User::getDataStore(Controller::request('userId'));
|
||||
|
||||
if(!$superUser->supervisedrelation) {
|
||||
$superUser->supervisedrelation = new Supervisedrelation();
|
||||
}
|
||||
|
||||
$superUser->supervisedrelation->sharedUserList->clear();
|
||||
foreach($userIdList as $userId) {
|
||||
$user = User::getDataStore($userId);
|
||||
|
||||
$superUser->supervisedrelation->sharedUserList->add($user);
|
||||
|
||||
}
|
||||
|
||||
$superUser->supervisedrelation->store();
|
||||
$superUser->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
|
||||
public function getUserIdListCleared(){
|
||||
$clearedList = array_unique(json_decode(Controller::request('userIdList')));
|
||||
$superUser = User::getDataStore(Controller::request('userId'));
|
||||
|
||||
foreach ($clearedList as $item) {
|
||||
if($item == $superUser->id) throw new Exception(ERRORS::SUPERVISOR_CAN_NOT_SUPERVISE_HIMSELF);
|
||||
}
|
||||
|
||||
return $clearedList;
|
||||
}
|
||||
|
||||
}
|
53
dist/api/controllers/user/enable.php
vendored
Executable file
53
dist/api/controllers/user/enable.php
vendored
Executable file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
use Respect\Validation\Validator as DataValidator;
|
||||
|
||||
/**
|
||||
* @api {post} /user/enable Ban email
|
||||
* @apiVersion 4.11.0
|
||||
*
|
||||
* @apiName Enable User
|
||||
*
|
||||
* @apiGroup User
|
||||
*
|
||||
* @apiDescription This path takes an user id and enables it
|
||||
*
|
||||
* @apiPermission staff1
|
||||
*
|
||||
* @apiParam {String} userId Id of the user to enable
|
||||
*
|
||||
* @apiUse NO_PERMISSION
|
||||
* @apiUse INVALID_USER
|
||||
* @apiUse ALREADY_ENABLED
|
||||
*
|
||||
* @apiSuccess {Object} data Empty object
|
||||
*
|
||||
*/
|
||||
class EnableUserController extends Controller {
|
||||
const PATH = '/enable';
|
||||
const METHOD = 'POST';
|
||||
|
||||
public function validations() {
|
||||
return [
|
||||
'permission' => 'staff_1',
|
||||
'requestData' => [
|
||||
'userId' => [
|
||||
'validation' => DataValidator::dataStoreId('user'),
|
||||
'error' => ERRORS::INVALID_USER
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function handler() {
|
||||
$user = User::getDataStore(Controller::request('userId'));
|
||||
|
||||
if(!$user->disabled) {
|
||||
throw new RequestException(ERRORS::ALREADY_ENABLED);
|
||||
}
|
||||
|
||||
$user->disabled = 0;
|
||||
$user->store();
|
||||
|
||||
Response::respondSuccess();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user