add last files (#1110)
This commit is contained in:
parent
6cb538616d
commit
950439bf47
|
@ -12,6 +12,7 @@ import FormField from 'core-components/form-field';
|
||||||
import SubmitButton from 'core-components/submit-button';
|
import SubmitButton from 'core-components/submit-button';
|
||||||
import Button from 'core-components/button';
|
import Button from 'core-components/button';
|
||||||
import TextEditor from 'core-components/text-editor';
|
import TextEditor from 'core-components/text-editor';
|
||||||
|
import Message from 'core-components/message';
|
||||||
|
|
||||||
class ArticleAddModal extends React.Component {
|
class ArticleAddModal extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -22,7 +23,8 @@ class ArticleAddModal extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
loading: false
|
loading: false,
|
||||||
|
errorMessage: false
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -31,6 +33,7 @@ class ArticleAddModal extends React.Component {
|
||||||
<Header title={i18n('ADD_ARTICLE')} description={i18n('ADD_ARTICLE_DESCRIPTION', {category: this.props.topicName})} />
|
<Header title={i18n('ADD_ARTICLE')} description={i18n('ADD_ARTICLE_DESCRIPTION', {category: this.props.topicName})} />
|
||||||
<Form onSubmit={this.onAddNewArticleFormSubmit.bind(this)} loading={this.state.loading}>
|
<Form onSubmit={this.onAddNewArticleFormSubmit.bind(this)} loading={this.state.loading}>
|
||||||
<FormField name="title" label={i18n('TITLE')} field="input" fieldProps={{size: 'large'}} validation="TITLE" required/>
|
<FormField name="title" label={i18n('TITLE')} field="input" fieldProps={{size: 'large'}} validation="TITLE" required/>
|
||||||
|
{this.state.errorMessage ? <Message type="error">{i18n(this.state.errorMessage)}</Message> : null}
|
||||||
<FormField name="content" label={i18n('CONTENT')} field="textarea" validation="TEXT_AREA" required fieldProps={{allowImages: this.props.allowAttachments}}/>
|
<FormField name="content" label={i18n('CONTENT')} field="textarea" validation="TEXT_AREA" required fieldProps={{allowImages: this.props.allowAttachments}}/>
|
||||||
<Button className="article-add-modal__cancel-button" type="link" onClick={(event) => {
|
<Button className="article-add-modal__cancel-button" type="link" onClick={(event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -57,13 +60,16 @@ class ArticleAddModal extends React.Component {
|
||||||
})
|
})
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
ModalContainer.closeModal();
|
ModalContainer.closeModal();
|
||||||
|
this.setState({
|
||||||
|
errorMessage: false
|
||||||
|
});
|
||||||
if(this.props.onChange) {
|
if(this.props.onChange) {
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch((e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false,
|
||||||
|
errorMessage: e.message
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import SubmitButton from 'core-components/submit-button';
|
||||||
import IconSelector from 'core-components/icon-selector';
|
import IconSelector from 'core-components/icon-selector';
|
||||||
import ColorSelector from 'core-components/color-selector';
|
import ColorSelector from 'core-components/color-selector';
|
||||||
import InfoTooltip from 'core-components/info-tooltip';
|
import InfoTooltip from 'core-components/info-tooltip';
|
||||||
|
import Message from 'core-components/message';
|
||||||
|
|
||||||
class TopicEditModal extends React.Component {
|
class TopicEditModal extends React.Component {
|
||||||
|
|
||||||
|
@ -26,14 +27,17 @@ class TopicEditModal extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
values: this.props.defaultValues || {title: '', icon: 'address-card', color: '#ff6900', private: false},
|
values: this.props.defaultValues || {title: '', icon: 'address-card', color: '#ff6900', private: false},
|
||||||
loading: false
|
loading: false,
|
||||||
|
errorMessage: false
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if (this.state.errorMessage ) console.log(this.state.errorMessage)
|
||||||
return (
|
return (
|
||||||
<div className="topic-edit-modal">
|
<div className="topic-edit-modal">
|
||||||
<Header title={i18n((this.props.addForm) ? 'ADD_TOPIC' : 'EDIT_TOPIC')} description={i18n((this.props.addForm) ? 'ADD_TOPIC_DESCRIPTION' : 'EDIT_TOPIC_DESCRIPTION')} />
|
<Header title={i18n((this.props.addForm) ? 'ADD_TOPIC' : 'EDIT_TOPIC')} description={i18n((this.props.addForm) ? 'ADD_TOPIC_DESCRIPTION' : 'EDIT_TOPIC_DESCRIPTION')} />
|
||||||
<Form values={this.state.values} onChange={this.onFormChange.bind(this)} onSubmit={this.onSubmit.bind(this)} loading={this.state.loading}>
|
<Form values={this.state.values} onChange={this.onFormChange.bind(this)} onSubmit={this.onSubmit.bind(this)} loading={this.state.loading}>
|
||||||
|
{this.state.errorMessage ? <Message type="error">{i18n(this.state.errorMessage)}</Message> : null}
|
||||||
<FormField name="title" label={i18n('TITLE')} fieldProps={{size: 'large'}} validation="TITLE" required />
|
<FormField name="title" label={i18n('TITLE')} fieldProps={{size: 'large'}} validation="TITLE" required />
|
||||||
<FormField name="icon" className="topic-edit-modal__icon" label={i18n('ICON')} decorator={IconSelector} />
|
<FormField name="icon" className="topic-edit-modal__icon" label={i18n('ICON')} decorator={IconSelector} />
|
||||||
<FormField name="color" className="topic-edit-modal__color" label={i18n('COLOR')} decorator={ColorSelector} />
|
<FormField name="color" className="topic-edit-modal__color" label={i18n('COLOR')} decorator={ColorSelector} />
|
||||||
|
@ -68,13 +72,16 @@ class TopicEditModal extends React.Component {
|
||||||
}
|
}
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.context.closeModal();
|
this.context.closeModal();
|
||||||
|
this.setState({
|
||||||
|
errorMessage: false
|
||||||
|
});
|
||||||
if(this.props.onChange) {
|
if(this.props.onChange) {
|
||||||
this.props.onChange();
|
this.props.onChange();
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch((e) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false
|
loading: false,
|
||||||
|
errorMessage: e.message
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import Form from 'core-components/form';
|
||||||
import FormField from 'core-components/form-field';
|
import FormField from 'core-components/form-field';
|
||||||
import SubmitButton from 'core-components/submit-button';
|
import SubmitButton from 'core-components/submit-button';
|
||||||
import TextEditor from 'core-components/text-editor';
|
import TextEditor from 'core-components/text-editor';
|
||||||
|
import Message from 'core-components/message';
|
||||||
|
|
||||||
class AdminPanelViewArticle extends React.Component {
|
class AdminPanelViewArticle extends React.Component {
|
||||||
|
|
||||||
|
@ -33,7 +34,8 @@ class AdminPanelViewArticle extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
editable: false
|
editable: false,
|
||||||
|
errorMessage: false
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -45,6 +47,7 @@ class AdminPanelViewArticle extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
console.log(this.state.errorMessage)
|
||||||
return (
|
return (
|
||||||
<div className="admin-panel-view-article">
|
<div className="admin-panel-view-article">
|
||||||
{(this.props.loading) ? <Loading /> : this.renderContent()}
|
{(this.props.loading) ? <Loading /> : this.renderContent()}
|
||||||
|
@ -96,6 +99,7 @@ class AdminPanelViewArticle extends React.Component {
|
||||||
</Button>
|
</Button>
|
||||||
<SubmitButton className="admin-panel-view-article__button" type="secondary" size="medium">{i18n('SAVE')}</SubmitButton>
|
<SubmitButton className="admin-panel-view-article__button" type="secondary" size="medium">{i18n('SAVE')}</SubmitButton>
|
||||||
</div>
|
</div>
|
||||||
|
{this.state.errorMessage ? <Message type="error">{i18n(this.state.errorMessage)}</Message> : null}
|
||||||
<FormField name="title" label={i18n('TITLE')} />
|
<FormField name="title" label={i18n('TITLE')} />
|
||||||
<FormField name="content" label={i18n('CONTENT')} field="textarea" validation="TEXT_AREA" required fieldProps={{allowImages: this.props.allowAttachments}}/>
|
<FormField name="content" label={i18n('CONTENT')} field="textarea" validation="TEXT_AREA" required fieldProps={{allowImages: this.props.allowAttachments}}/>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -139,7 +143,12 @@ class AdminPanelViewArticle extends React.Component {
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.props.dispatch(ArticlesActions.retrieveArticles());
|
this.props.dispatch(ArticlesActions.retrieveArticles());
|
||||||
this.setState({
|
this.setState({
|
||||||
editable: false
|
editable: false,
|
||||||
|
errorMessage: false
|
||||||
|
})
|
||||||
|
}).catch((e) => {
|
||||||
|
this.setState({
|
||||||
|
errorMessage: e.message
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,6 +410,8 @@ export default {
|
||||||
'INVALID_SUPERVISED_USERS': 'Invalid supervised users',
|
'INVALID_SUPERVISED_USERS': 'Invalid supervised users',
|
||||||
'SUPERVISOR_CAN_NOT_SUPERVISE_HIMSELF': 'Supervisor can not supervise himself',
|
'SUPERVISOR_CAN_NOT_SUPERVISE_HIMSELF': 'Supervisor can not supervise himself',
|
||||||
'NAME_ALREADY_USED': 'Name already used',
|
'NAME_ALREADY_USED': 'Name already used',
|
||||||
|
'CONTENT_ALREADY_USED': 'Content already used',
|
||||||
|
'TITLE_ALREADY_USED': 'Title already used',
|
||||||
|
|
||||||
//MESSAGES
|
//MESSAGES
|
||||||
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',
|
'SIGNUP_SUCCESS': 'You have registered successfully in our support system.',
|
||||||
|
|
|
@ -19,9 +19,10 @@ DataValidator::with('CustomValidations', true);
|
||||||
* @apiParam {String} iconColor Icon's color 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.
|
* @apiParam {Boolean} private Indicates if the topic is not shown to users.
|
||||||
*
|
*
|
||||||
* @apiUse NO_PERMISSION
|
* @apiUse NO_PERMISSION
|
||||||
* @apiUse INVALID_NAME
|
* @apiUse INVALID_TITLE
|
||||||
*
|
* @apiUse NAME_ALREADY_USED
|
||||||
|
*
|
||||||
* @apiSuccess {Object} data Topic info
|
* @apiSuccess {Object} data Topic info
|
||||||
* @apiSuccess {Number} data.topicId Topic id
|
* @apiSuccess {Number} data.topicId Topic id
|
||||||
*
|
*
|
||||||
|
@ -37,19 +38,30 @@ class AddTopicController extends Controller {
|
||||||
'requestData' => [
|
'requestData' => [
|
||||||
'name' => [
|
'name' => [
|
||||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||||
'error' => ERRORS::INVALID_NAME
|
'error' => ERRORS::INVALID_TITLE
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handler() {
|
public function handler() {
|
||||||
|
|
||||||
|
$name = Controller::request('name', true);
|
||||||
|
$icon = Controller::request('icon');
|
||||||
|
$iconColor = Controller::request('iconColor');
|
||||||
|
$private = Controller::request('private') ? 1 : 0;
|
||||||
|
$CreatedTopic = Topic::getDataStore($name, 'name');
|
||||||
|
|
||||||
|
if(!$CreatedTopic->isNull()){
|
||||||
|
throw new RequestException(ERRORS::NAME_ALREADY_USED);
|
||||||
|
}
|
||||||
|
|
||||||
$topic = new Topic();
|
$topic = new Topic();
|
||||||
$topic->setProperties([
|
$topic->setProperties([
|
||||||
'name' => Controller::request('name', true),
|
'name' => $name,
|
||||||
'icon' => Controller::request('icon'),
|
'icon' => $icon,
|
||||||
'iconColor' => Controller::request('iconColor'),
|
'iconColor' => $iconColor,
|
||||||
'private' => Controller::request('private') ? 1 : 0
|
'private' => $private
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Log::createLog('ADD_TOPIC', $topic->name);
|
Log::createLog('ADD_TOPIC', $topic->name);
|
||||||
|
|
|
@ -25,6 +25,8 @@ DataValidator::with('CustomValidations', true);
|
||||||
* @apiUse INVALID_TITLE
|
* @apiUse INVALID_TITLE
|
||||||
* @apiUse INVALID_CONTENT
|
* @apiUse INVALID_CONTENT
|
||||||
* @apiUse INVALID_TOPIC
|
* @apiUse INVALID_TOPIC
|
||||||
|
* @apiUse TITLE_ALREADY_USED
|
||||||
|
* @apiUse CONTENT_ALREADY_USED
|
||||||
*
|
*
|
||||||
* @apiSuccess {Object} data Article info
|
* @apiSuccess {Object} data Article info
|
||||||
* @apiSuccess {Number} data.articleId Article id
|
* @apiSuccess {Number} data.articleId Article id
|
||||||
|
@ -39,7 +41,7 @@ class AddArticleController extends Controller {
|
||||||
'permission' => 'staff_2',
|
'permission' => 'staff_2',
|
||||||
'requestData' => [
|
'requestData' => [
|
||||||
'title' => [
|
'title' => [
|
||||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TITLE, LengthConfig::MAX_LENGTH_TITLE),
|
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||||
'error' => ERRORS::INVALID_TITLE
|
'error' => ERRORS::INVALID_TITLE
|
||||||
],
|
],
|
||||||
'content' => [
|
'content' => [
|
||||||
|
@ -56,14 +58,26 @@ class AddArticleController extends Controller {
|
||||||
|
|
||||||
public function handler() {
|
public function handler() {
|
||||||
$content = Controller::request('content', true);
|
$content = Controller::request('content', true);
|
||||||
|
$title = Controller::request('title', true);
|
||||||
|
$createdArticleTookByTitle = Article::getDataStore($title,'title');
|
||||||
|
$createdArticleTookByContent = Article::getDataStore($content,'content');
|
||||||
|
|
||||||
|
if(!$createdArticleTookByTitle->isNull()){
|
||||||
|
throw new RequestException(ERRORS::TITLE_ALREADY_USED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$createdArticleTookByContent->isNull()){
|
||||||
|
throw new RequestException(ERRORS::CONTENT_ALREADY_USED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$fileUploader = FileUploader::getInstance();
|
$fileUploader = FileUploader::getInstance();
|
||||||
$fileUploader->setPermission(FileManager::PERMISSION_ARTICLE);
|
$fileUploader->setPermission(FileManager::PERMISSION_ARTICLE);
|
||||||
$imagePaths = $this->uploadImages(true);
|
$imagePaths = $this->uploadImages(true);
|
||||||
|
|
||||||
$article = new Article();
|
$article = new Article();
|
||||||
$article->setProperties([
|
$article->setProperties([
|
||||||
'title' => Controller::request('title', true),
|
'title' => $title,
|
||||||
'content' => $this->replaceWithImagePaths($imagePaths, $content),
|
'content' => $this->replaceWithImagePaths($imagePaths, $content),
|
||||||
'lastEdited' => Date::getCurrentDate(),
|
'lastEdited' => Date::getCurrentDate(),
|
||||||
'position' => Controller::request('position') || 1
|
'position' => Controller::request('position') || 1
|
||||||
|
|
|
@ -22,7 +22,8 @@ DataValidator::with('CustomValidations', true);
|
||||||
*
|
*
|
||||||
* @apiUse NO_PERMISSION
|
* @apiUse NO_PERMISSION
|
||||||
* @apiUse INVALID_TOPIC
|
* @apiUse INVALID_TOPIC
|
||||||
* @apiUse INVALID_NAME
|
* @apiUse INVALID_TITLE
|
||||||
|
* @apiUse NAME_ALREADY_USED
|
||||||
*
|
*
|
||||||
* @apiSuccess {Object} data Empty object
|
* @apiSuccess {Object} data Empty object
|
||||||
*
|
*
|
||||||
|
@ -42,7 +43,7 @@ class EditTopicController extends Controller {
|
||||||
],
|
],
|
||||||
'name' => [
|
'name' => [
|
||||||
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||||
'error' => ERRORS::INVALID_NAME
|
'error' => ERRORS::INVALID_TITLE
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
@ -50,20 +51,29 @@ class EditTopicController extends Controller {
|
||||||
|
|
||||||
public function handler() {
|
public function handler() {
|
||||||
$topic = Topic::getDataStore(Controller::request('topicId'));
|
$topic = Topic::getDataStore(Controller::request('topicId'));
|
||||||
|
$name = Controller::request('name');
|
||||||
|
$iconColor = Controller::request('iconColor');
|
||||||
|
$private = Controller::request('private');
|
||||||
|
$icon = Controller::request('icon');
|
||||||
|
$createdArticleTookByName = Topic::getDataStore($name, 'name');
|
||||||
|
|
||||||
if(Controller::request('name')) {
|
if(!$createdArticleTookByName->isNull() && $topic->id !== $createdArticleTookByName->id){
|
||||||
|
throw new RequestException(ERRORS::NAME_ALREADY_USED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if($name) {
|
||||||
$topic->name = Controller::request('name', true);
|
$topic->name = Controller::request('name', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Controller::request('iconColor')) {
|
if($iconColor) {
|
||||||
$topic->iconColor = Controller::request('iconColor');
|
$topic->iconColor = $iconColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Controller::request('icon')) {
|
if($icon) {
|
||||||
$topic->icon = Controller::request('icon');
|
$topic->icon = $icon;
|
||||||
}
|
}
|
||||||
if (Controller::request('private') !== null) {
|
if ($private !== null) {
|
||||||
$topic->private = Controller::request('private');
|
$topic->private = $private;
|
||||||
}
|
}
|
||||||
|
|
||||||
$topic->store();
|
$topic->store();
|
||||||
|
|
|
@ -26,7 +26,9 @@ DataValidator::with('CustomValidations', true);
|
||||||
* @apiUse INVALID_TOPIC
|
* @apiUse INVALID_TOPIC
|
||||||
* @apiUse INVALID_FILE
|
* @apiUse INVALID_FILE
|
||||||
* @apiUse INVALID_TITLE
|
* @apiUse INVALID_TITLE
|
||||||
*
|
* @apiUse CONTENT_ALREADY_USED
|
||||||
|
* @apiUse TITLE_ALREADY_USED
|
||||||
|
*
|
||||||
* @apiSuccess {Object} data Empty object
|
* @apiSuccess {Object} data Empty object
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -44,14 +46,17 @@ class EditArticleController extends Controller {
|
||||||
'error' => ERRORS::INVALID_TOPIC
|
'error' => ERRORS::INVALID_TOPIC
|
||||||
],
|
],
|
||||||
'title' => [
|
'title' => [
|
||||||
'validation' => DataValidator::oneOf(
|
'validation' => DataValidator::OneOf(
|
||||||
DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_TITLE, LengthConfig::MAX_LENGTH_TITLE),
|
DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||||
DataValidator::nullType()
|
DataValidator::nullType()
|
||||||
),
|
),
|
||||||
'error' => ERRORS::INVALID_TITLE
|
'error' => ERRORS::INVALID_TITLE
|
||||||
],
|
],
|
||||||
'content' => [
|
'content' => [
|
||||||
'validation' => DataValidator::oneOf(DataValidator::content(),DataValidator::nullType()),
|
'validation' => DataValidator::oneOf(
|
||||||
|
DataValidator::content(),
|
||||||
|
DataValidator::nullType()
|
||||||
|
),
|
||||||
'error' => ERRORS::INVALID_CONTENT
|
'error' => ERRORS::INVALID_CONTENT
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -59,10 +64,24 @@ class EditArticleController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handler() {
|
public function handler() {
|
||||||
|
$topicId = Controller::request('topicId');
|
||||||
|
$content = Controller::request('content', true);
|
||||||
|
$title = Controller::request('title');
|
||||||
|
|
||||||
$article = Article::getDataStore(Controller::request('articleId'));
|
$article = Article::getDataStore(Controller::request('articleId'));
|
||||||
|
$createdArticleTookByTitle = Article::getDataStore($title, 'title');
|
||||||
|
$createdArticleTookByContent = Article::getDataStore($content, 'content');
|
||||||
|
|
||||||
if (Controller::request('topicId')) {
|
if(!$createdArticleTookByTitle->isNull() && $article->title !== $createdArticleTookByTitle->title){
|
||||||
$newArticleTopic = Topic::getDataStore(Controller::request('topicId'));
|
throw new RequestException(ERRORS::TITLE_ALREADY_USED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$createdArticleTookByContent->isNull() && $article->content !== $createdArticleTookByContent->content){
|
||||||
|
throw new RequestException(ERRORS::CONTENT_ALREADY_USED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($topicId) {
|
||||||
|
$newArticleTopic = Topic::getDataStore($topicId);
|
||||||
|
|
||||||
if (!$newArticleTopic->isNull()) {
|
if (!$newArticleTopic->isNull()) {
|
||||||
$article->topic = $newArticleTopic;
|
$article->topic = $newArticleTopic;
|
||||||
|
@ -72,18 +91,17 @@ class EditArticleController extends Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Controller::request('content')) {
|
if($content) {
|
||||||
$fileUploader = FileUploader::getInstance();
|
$fileUploader = FileUploader::getInstance();
|
||||||
$fileUploader->setPermission(FileManager::PERMISSION_ARTICLE);
|
$fileUploader->setPermission(FileManager::PERMISSION_ARTICLE);
|
||||||
|
|
||||||
$content = Controller::request('content', true);
|
|
||||||
$imagePaths = $this->uploadImages(true);
|
$imagePaths = $this->uploadImages(true);
|
||||||
|
|
||||||
$article->content = $this->replaceWithImagePaths($imagePaths, $content);
|
$article->content = $this->replaceWithImagePaths($imagePaths, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Controller::request('title')) {
|
if($title) {
|
||||||
$article->title = Controller::request('title');
|
$article->title = $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Controller::request('position')) {
|
if(Controller::request('position')) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ DataValidator::with('CustomValidations', true);
|
||||||
* @apiUse NO_PERMISSION
|
* @apiUse NO_PERMISSION
|
||||||
* @apiUse INVALID_NAME
|
* @apiUse INVALID_NAME
|
||||||
* @apiUse INVALID_DEPARTMENT
|
* @apiUse INVALID_DEPARTMENT
|
||||||
|
* @apiUse NAME_ALREADY_USED
|
||||||
*
|
*
|
||||||
* @apiSuccess {Object} data Empty object
|
* @apiSuccess {Object} data Empty object
|
||||||
*
|
*
|
||||||
|
@ -39,10 +40,7 @@ class EditDepartmentController extends Controller {
|
||||||
'error' => ERRORS::INVALID_DEPARTMENT
|
'error' => ERRORS::INVALID_DEPARTMENT
|
||||||
],
|
],
|
||||||
'name' => [
|
'name' => [
|
||||||
'validation' => DataValidator::AllOf(
|
'validation' => DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
||||||
DataValidator::notBlank()->length(LengthConfig::MIN_LENGTH_NAME, LengthConfig::MAX_LENGTH_NAME),
|
|
||||||
DataValidator::ValidDepartmentName()
|
|
||||||
),
|
|
||||||
'error' => ERRORS::INVALID_NAME
|
'error' => ERRORS::INVALID_NAME
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
@ -55,6 +53,11 @@ class EditDepartmentController extends Controller {
|
||||||
$private = Controller::request('private');
|
$private = Controller::request('private');
|
||||||
|
|
||||||
$departmentInstance = Department::getDataStore($departmentId);
|
$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()){
|
if($private && $departmentId == Setting::getSetting('default-department-id')->getValue()){
|
||||||
throw new RequestException(ERRORS::DEFAULT_DEPARTMENT_CAN_NOT_BE_PRIVATE);
|
throw new RequestException(ERRORS::DEFAULT_DEPARTMENT_CAN_NOT_BE_PRIVATE);
|
||||||
|
|
|
@ -24,9 +24,17 @@
|
||||||
* @apiError {String} INVALID_TITLE The title is invalid, probably too short.
|
* @apiError {String} INVALID_TITLE The title is invalid, probably too short.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @apiDefine INVALID_CONTENT
|
* @apiDefine TITLE_ALREADY_USED
|
||||||
|
* @apiError {String} TITLE_ALREADY_USED The title is already in use.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @apiDefine INVALID_CONTENT
|
||||||
* @apiError {String} INVALID_CONTENT The content is invalid, probably to short.
|
* @apiError {String} INVALID_CONTENT The content is invalid, probably to short.
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @apiDefine CONTENT_ALREADY_USED
|
||||||
|
* @apiError {String} CONTENT_ALREADY_USED The content is already in use.
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* @apiDefine INVALID_EMAIL
|
* @apiDefine INVALID_EMAIL
|
||||||
* @apiError {String} INVALID_EMAIL The email is invalid or already exists.
|
* @apiError {String} INVALID_EMAIL The email is invalid or already exists.
|
||||||
|
@ -335,7 +343,9 @@ class ERRORS {
|
||||||
const TAG_EXISTS = 'TAG_EXISTS';
|
const TAG_EXISTS = 'TAG_EXISTS';
|
||||||
const NO_PERMISSION = 'NO_PERMISSION';
|
const NO_PERMISSION = 'NO_PERMISSION';
|
||||||
const INVALID_TITLE = 'INVALID_TITLE';
|
const INVALID_TITLE = 'INVALID_TITLE';
|
||||||
|
const TITLE_ALREADY_USED = 'TITLE_ALREADY_USED';
|
||||||
const INVALID_CONTENT = 'INVALID_CONTENT';
|
const INVALID_CONTENT = 'INVALID_CONTENT';
|
||||||
|
const CONTENT_ALREADY_USED = 'CONTENT_ALREADY_USED';
|
||||||
const INVALID_EMAIL = 'INVALID_EMAIL';
|
const INVALID_EMAIL = 'INVALID_EMAIL';
|
||||||
const INVALID_PASSWORD = 'INVALID_PASSWORD';
|
const INVALID_PASSWORD = 'INVALID_PASSWORD';
|
||||||
const INVALID_NAME = 'INVALID_NAME';
|
const INVALID_NAME = 'INVALID_NAME';
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace CustomValidations;
|
||||||
|
|
||||||
|
use Respect\Validation\Rules\AbstractRule;
|
||||||
|
|
||||||
|
class ValidArticleContent extends AbstractRule {
|
||||||
|
|
||||||
|
public function validate($content) {
|
||||||
|
$article = \Article::getDataStore($content, 'content');
|
||||||
|
return $article->isNull();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace CustomValidations;
|
||||||
|
|
||||||
|
use Respect\Validation\Rules\AbstractRule;
|
||||||
|
|
||||||
|
class ValidArticleName extends AbstractRule {
|
||||||
|
|
||||||
|
public function validate($name) {
|
||||||
|
$article = \Article::getDataStore($name, 'title');
|
||||||
|
return $article->isNull();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace CustomValidations;
|
||||||
|
|
||||||
|
use Respect\Validation\Rules\AbstractRule;
|
||||||
|
|
||||||
|
class ValidTopicName extends AbstractRule {
|
||||||
|
|
||||||
|
public function validate($name) {
|
||||||
|
$topic = \Topic::getDataStore($name, 'name');
|
||||||
|
return $topic->isNull();
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,6 +48,32 @@ describe 'Article path' do
|
||||||
(lastLog['type']).should.equal('ADD_ARTICLE')
|
(lastLog['type']).should.equal('ADD_ARTICLE')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should fail if articles data already exists' do
|
||||||
|
|
||||||
|
result = request('/article/add', {
|
||||||
|
title: 'Some article',
|
||||||
|
content: 'this content is unique',
|
||||||
|
topicId: @topic_id,
|
||||||
|
position: 1,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
(result['status']).should.equal('fail')
|
||||||
|
(result['message']).should.equal('TITLE_ALREADY_USED')
|
||||||
|
|
||||||
|
result = request('/article/add', {
|
||||||
|
title: 'unique title',
|
||||||
|
content: 'This is an article about server management.',
|
||||||
|
topicId: @topic_id,
|
||||||
|
position: 1,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('fail')
|
||||||
|
(result['message']).should.equal('CONTENT_ALREADY_USED')
|
||||||
|
end
|
||||||
|
|
||||||
it 'should edit article' do
|
it 'should edit article' do
|
||||||
result = request('/article/edit', {
|
result = request('/article/edit', {
|
||||||
articleId: @article_id,
|
articleId: @article_id,
|
||||||
|
@ -67,6 +93,77 @@ describe 'Article path' do
|
||||||
(lastLog['type']).should.equal('EDIT_ARTICLE')
|
(lastLog['type']).should.equal('EDIT_ARTICLE')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should fail if edit article has already used data' do
|
||||||
|
result = request('/article/add', {
|
||||||
|
title: 'unique title1.5',
|
||||||
|
content: 'This is an article about server management1.5.',
|
||||||
|
topicId: @topic_id,
|
||||||
|
position: 1,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
|
||||||
|
result = request('/article/add', {
|
||||||
|
title: 'unique title2',
|
||||||
|
content: 'This is an article about server management22.',
|
||||||
|
topicId: @topic_id,
|
||||||
|
position: 1,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
lastArticle = $database.getLastRow('article')
|
||||||
|
|
||||||
|
result = request('/article/edit', {
|
||||||
|
articleId: lastArticle['id'],
|
||||||
|
content: 'This is an article about server management1.5.',
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('fail')
|
||||||
|
(result['message']).should.equal('CONTENT_ALREADY_USED')
|
||||||
|
|
||||||
|
result = request('/article/edit', {
|
||||||
|
articleId: lastArticle['id'],
|
||||||
|
title: 'unique title1.5',
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('fail')
|
||||||
|
(result['message']).should.equal('TITLE_ALREADY_USED')
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should success if change for the same date' do
|
||||||
|
result = request('/article/add', {
|
||||||
|
title: 'unique article',
|
||||||
|
content: 'this content is unique pt2',
|
||||||
|
topicId: @topic_id,
|
||||||
|
position: 1,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
|
||||||
|
lastArticle = $database.getLastRow('article')
|
||||||
|
|
||||||
|
result = request('/article/edit', {
|
||||||
|
articleId: lastArticle['id'],
|
||||||
|
title: 'unique article',
|
||||||
|
content: 'this content is unique pt2',
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
end
|
||||||
|
|
||||||
it 'should edit article topic' do
|
it 'should edit article topic' do
|
||||||
request('/article/add-topic', {
|
request('/article/add-topic', {
|
||||||
name: 'Software installation',
|
name: 'Software installation',
|
||||||
|
@ -107,38 +204,44 @@ describe 'Article path' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should retrieve all articles' do
|
it 'should retrieve all articles' do
|
||||||
request('/article/add', {
|
|
||||||
title: 'Some article',
|
|
||||||
content: 'This is an article about server management.',
|
|
||||||
topicId: @topic_id,
|
|
||||||
position: 1,
|
|
||||||
csrf_userid: $csrf_userid,
|
|
||||||
csrf_token: $csrf_token
|
|
||||||
})
|
|
||||||
result = request('/article/get-all', {
|
result = request('/article/get-all', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
csrf_token: $csrf_token
|
csrf_token: $csrf_token
|
||||||
})
|
})
|
||||||
(result['status']).should.equal('success')
|
(result['status']).should.equal('success')
|
||||||
|
|
||||||
(result['data'][0]['name']).should.equal('Server management')
|
(result['data'][0]['name']).should.equal('Valid name')
|
||||||
(result['data'][0]['icon']).should.equal('cogs')
|
(result['data'][0]['icon']).should.equal('flag')
|
||||||
(result['data'][0]['iconColor']).should.equal('red')
|
(result['data'][0]['iconColor']).should.equal('pink')
|
||||||
(result['data'][0]['private']).should.equal('0')
|
(result['data'][0]['private']).should.equal('1')
|
||||||
(result['data'][1]['name']).should.equal('Private Topic')
|
|
||||||
|
(result['data'][1]['name']).should.equal('Server management')
|
||||||
(result['data'][1]['icon']).should.equal('cogs')
|
(result['data'][1]['icon']).should.equal('cogs')
|
||||||
(result['data'][1]['iconColor']).should.equal('green')
|
(result['data'][1]['iconColor']).should.equal('red')
|
||||||
(result['data'][1]['private']).should.equal('1')
|
(result['data'][1]['private']).should.equal('0')
|
||||||
(result['data'][2]['name']).should.equal('Software installation')
|
|
||||||
(result['data'][2]['icon']).should.equal('photo')
|
|
||||||
(result['data'][2]['iconColor']).should.equal('blue')
|
|
||||||
(result['data'][2]['private']).should.equal('0')
|
|
||||||
|
|
||||||
(result['data'][0]['articles'][0]['title']).should.equal('Some article')
|
(result['data'][2]['name']).should.equal('Private Topic')
|
||||||
(result['data'][0]['articles'][0]['content']).should.equal('This is an article about server management.')
|
(result['data'][2]['icon']).should.equal('cogs')
|
||||||
(result['data'][0]['articles'][0]['position']).should.equal('1')
|
(result['data'][2]['iconColor']).should.equal('green')
|
||||||
|
(result['data'][2]['private']).should.equal('1')
|
||||||
|
|
||||||
|
(result['data'][3]['name']).should.equal('Software installation')
|
||||||
|
(result['data'][3]['icon']).should.equal('photo')
|
||||||
|
(result['data'][3]['iconColor']).should.equal('blue')
|
||||||
|
(result['data'][3]['private']).should.equal('0')
|
||||||
|
|
||||||
|
(result['data'][1]['articles'][0]['title']).should.equal('unique title1.5')
|
||||||
|
(result['data'][1]['articles'][0]['content']).should.equal('This is an article about server management1.5.')
|
||||||
|
(result['data'][1]['articles'][0]['position']).should.equal('1')
|
||||||
|
(result['data'][1]['articles'][1]['title']).should.equal('unique title2')
|
||||||
|
(result['data'][1]['articles'][1]['content']).should.equal('This is an article about server management22.')
|
||||||
|
(result['data'][1]['articles'][1]['position']).should.equal('1')
|
||||||
|
(result['data'][1]['articles'][2]['title']).should.equal('unique article')
|
||||||
|
(result['data'][1]['articles'][2]['content']).should.equal('this content is unique pt2')
|
||||||
|
(result['data'][1]['articles'][2]['position']).should.equal('1')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should retrieve public departments' do
|
it 'should retrieve public departments' do
|
||||||
Scripts.logout()
|
Scripts.logout()
|
||||||
Scripts.login('tyrion@opensupports.com', 'tyrionl')
|
Scripts.login('tyrion@opensupports.com', 'tyrionl')
|
||||||
|
|
|
@ -24,6 +24,19 @@ describe 'Topic paths' do
|
||||||
(lastLog['type']).should.equal('ADD_TOPIC')
|
(lastLog['type']).should.equal('ADD_TOPIC')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should success if topic has same name' do
|
||||||
|
result = request('/article/edit-topic', {
|
||||||
|
topicId: 1,
|
||||||
|
name: 'Server management',
|
||||||
|
iconColor: 'blue',
|
||||||
|
private: 1,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
end
|
||||||
|
|
||||||
it 'should edit topic correctly' do
|
it 'should edit topic correctly' do
|
||||||
result = request('/article/edit-topic', {
|
result = request('/article/edit-topic', {
|
||||||
topicId: 1,
|
topicId: 1,
|
||||||
|
@ -43,6 +56,47 @@ describe 'Topic paths' do
|
||||||
(topic['private']).should.equal(1)
|
(topic['private']).should.equal(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should fail if data is already in use' do
|
||||||
|
result = request('/article/add-topic', {
|
||||||
|
name: 'Installation issues',
|
||||||
|
icon: 'cogs',
|
||||||
|
iconColor: 'red',
|
||||||
|
private: 0,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('fail')
|
||||||
|
(result['message']).should.equal('NAME_ALREADY_USED')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should edit topic if data is right without name' do
|
||||||
|
result = request('/article/add-topic', {
|
||||||
|
name: 'Valid name',
|
||||||
|
icon: 'cogs',
|
||||||
|
iconColor: 'red',
|
||||||
|
private: 0,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
|
||||||
|
topic = $database.getLastRow('topic')
|
||||||
|
|
||||||
|
result = request('/article/edit-topic', {
|
||||||
|
name: 'Valid name',
|
||||||
|
topicId: topic['id'],
|
||||||
|
iconColor: 'pink',
|
||||||
|
icon: 'flag',
|
||||||
|
private: 1,
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
end
|
||||||
|
|
||||||
it 'should delete topic correctly' do
|
it 'should delete topic correctly' do
|
||||||
result = request('/article/delete-topic', {
|
result = request('/article/delete-topic', {
|
||||||
topicId: 1,
|
topicId: 1,
|
||||||
|
|
|
@ -162,11 +162,12 @@ class Scripts
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.createDepartment(nameDepartment = 'validnameDepartment')
|
def self.createDepartment(nameDepartment, private = 0)
|
||||||
request('/system/add-department', {
|
request('/system/add-department', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
csrf_token: $csrf_token,
|
csrf_token: $csrf_token,
|
||||||
name: nameDepartment
|
name: nameDepartment,
|
||||||
|
private: private
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -44,19 +44,39 @@ describe'system/edit-department' do
|
||||||
result['status'].should.equal('fail')
|
result['status'].should.equal('fail')
|
||||||
result['message'].should.equal('INVALID_NAME')
|
result['message'].should.equal('INVALID_NAME')
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should success if you change for the same name' do
|
||||||
|
Scripts.createDepartment('thisisAnewName')
|
||||||
|
department = $database.getLastRow('department')
|
||||||
|
|
||||||
|
result = request('/system/edit-department', {
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token,
|
||||||
|
name: department['name'],
|
||||||
|
departmentId: department['id'],
|
||||||
|
private:1
|
||||||
|
})
|
||||||
|
|
||||||
|
result['status'].should.equal('success')
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shouild fail if you use an used name' do
|
||||||
|
Scripts.createDepartment('thistitleisunique')
|
||||||
|
|
||||||
lastDepartment = $database.getLastRow('department')
|
lastDepartment = $database.getLastRow('department')
|
||||||
|
|
||||||
result = request('/system/edit-department', {
|
result = request('/system/edit-department', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
csrf_token: $csrf_token,
|
csrf_token: $csrf_token,
|
||||||
name: lastDepartment['name'],
|
name: 'thisisAnewName',
|
||||||
departmentId: 4
|
departmentId: lastDepartment['id'],
|
||||||
|
private:1
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
result['status'].should.equal('fail')
|
result['status'].should.equal('fail')
|
||||||
result['message'].should.equal('INVALID_NAME')
|
result['message'].should.equal('NAME_ALREADY_USED')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue