Add language in import and export form, with handle by FormatterData
modifié: core/lib/Thelia/Controller/Admin/ExportController.php modifié: core/lib/Thelia/Controller/Admin/ImportController.php modifié: core/lib/Thelia/Core/FileFormat/Formatting/FormatterData.php modifié: core/lib/Thelia/Form/ExportForm.php modifié: core/lib/Thelia/Form/ImportForm.php modifié: templates/backOffice/default/ajax/export-modal.html modifié: templates/backOffice/default/ajax/import-modal.html modifié: templates/backOffice/default/export-page.html modifié: templates/backOffice/default/import-page.html
This commit is contained in:
@@ -30,6 +30,8 @@ use Thelia\ImportExport\Export\ExportHandler;
|
|||||||
use Thelia\ImportExport\Export\ImagesExportInterface;
|
use Thelia\ImportExport\Export\ImagesExportInterface;
|
||||||
use Thelia\Model\ExportCategoryQuery;
|
use Thelia\Model\ExportCategoryQuery;
|
||||||
use Thelia\Model\ExportQuery;
|
use Thelia\Model\ExportQuery;
|
||||||
|
use Thelia\Model\Lang;
|
||||||
|
use Thelia\Model\LangQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ExportController
|
* Class ExportController
|
||||||
@@ -88,6 +90,10 @@ class ExportController extends BaseAdminController
|
|||||||
try {
|
try {
|
||||||
$boundForm = $this->validateForm($form);
|
$boundForm = $this->validateForm($form);
|
||||||
|
|
||||||
|
$lang = LangQuery::create()->findPk(
|
||||||
|
$boundForm->get("language")->getData()
|
||||||
|
);
|
||||||
|
|
||||||
$archiveBuilder = null;
|
$archiveBuilder = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +121,8 @@ class ExportController extends BaseAdminController
|
|||||||
$export->getHandleClassInstance($this->container),
|
$export->getHandleClassInstance($this->container),
|
||||||
$archiveBuilder,
|
$archiveBuilder,
|
||||||
$boundForm->get("images")->getData(),
|
$boundForm->get("images")->getData(),
|
||||||
$boundForm->get("documents")->getData()
|
$boundForm->get("documents")->getData(),
|
||||||
|
$lang
|
||||||
);
|
);
|
||||||
|
|
||||||
} catch (FormValidationException $e) {
|
} catch (FormValidationException $e) {
|
||||||
@@ -153,6 +160,7 @@ class ExportController extends BaseAdminController
|
|||||||
AbstractFormatter $formatter,
|
AbstractFormatter $formatter,
|
||||||
ExportHandler $handler,
|
ExportHandler $handler,
|
||||||
AbstractArchiveBuilder $archiveBuilder = null,
|
AbstractArchiveBuilder $archiveBuilder = null,
|
||||||
|
Lang $lang,
|
||||||
$includeImages = false,
|
$includeImages = false,
|
||||||
$includeDocuments = false
|
$includeDocuments = false
|
||||||
) {
|
) {
|
||||||
@@ -160,7 +168,7 @@ class ExportController extends BaseAdminController
|
|||||||
* Build an event containing the formatter and the handler.
|
* Build an event containing the formatter and the handler.
|
||||||
* Used for specific configuration (e.g: XML node names)
|
* Used for specific configuration (e.g: XML node names)
|
||||||
*/
|
*/
|
||||||
$data = $handler->buildFormatterData();
|
$data = $handler->buildFormatterData()->setLang($lang);
|
||||||
$event = new ImportExportEvent($formatter, $handler , $data);
|
$event = new ImportExportEvent($formatter, $handler , $data);
|
||||||
|
|
||||||
$filename = $formatter::FILENAME . "." . $formatter->getExtension();
|
$filename = $formatter::FILENAME . "." . $formatter->getExtension();
|
||||||
@@ -288,6 +296,7 @@ class ExportController extends BaseAdminController
|
|||||||
$this->getParserContext()
|
$this->getParserContext()
|
||||||
->set("HAS_IMAGES", $export->hasImages($this->container))
|
->set("HAS_IMAGES", $export->hasImages($this->container))
|
||||||
->set("HAS_DOCUMENTS", $export->hasDocuments($this->container))
|
->set("HAS_DOCUMENTS", $export->hasDocuments($this->container))
|
||||||
|
->set("CURRENT_LANG_ID", $this->getSession()->getLang()->getId())
|
||||||
;
|
;
|
||||||
|
|
||||||
/** Then render the form */
|
/** Then render the form */
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ use Thelia\Form\ImportForm;
|
|||||||
use Thelia\ImportExport\Import\ImportHandler;
|
use Thelia\ImportExport\Import\ImportHandler;
|
||||||
use Thelia\Model\ImportCategoryQuery;
|
use Thelia\Model\ImportCategoryQuery;
|
||||||
use Thelia\Model\ImportQuery;
|
use Thelia\Model\ImportQuery;
|
||||||
|
use Thelia\Model\Lang;
|
||||||
|
use Thelia\Model\LangQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ImportController
|
* Class ImportController
|
||||||
@@ -79,6 +81,10 @@ class ImportController extends BaseAdminController
|
|||||||
try {
|
try {
|
||||||
$boundForm = $this->validateForm($form);
|
$boundForm = $this->validateForm($form);
|
||||||
|
|
||||||
|
$lang = LangQuery::create()->findPk(
|
||||||
|
$boundForm->get("language")->getData()
|
||||||
|
);
|
||||||
|
|
||||||
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
|
/** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
|
||||||
$file = $boundForm->get("file_upload")->getData();
|
$file = $boundForm->get("file_upload")->getData();
|
||||||
|
|
||||||
@@ -139,7 +145,8 @@ class ImportController extends BaseAdminController
|
|||||||
$content,
|
$content,
|
||||||
$handler,
|
$handler,
|
||||||
$formatter,
|
$formatter,
|
||||||
$archiveBuilder
|
$archiveBuilder,
|
||||||
|
$lang
|
||||||
);
|
);
|
||||||
|
|
||||||
} catch (FormValidationException $e) {
|
} catch (FormValidationException $e) {
|
||||||
@@ -282,14 +289,18 @@ class ImportController extends BaseAdminController
|
|||||||
$content,
|
$content,
|
||||||
ImportHandler $handler,
|
ImportHandler $handler,
|
||||||
AbstractFormatter $formatter = null,
|
AbstractFormatter $formatter = null,
|
||||||
AbstractArchiveBuilder $archiveBuilder = null
|
AbstractArchiveBuilder $archiveBuilder = null,
|
||||||
|
Lang $lang = null
|
||||||
) {
|
) {
|
||||||
$event = new ImportExportEvent($formatter, $handler, null, $archiveBuilder);
|
$event = new ImportExportEvent($formatter, $handler, null, $archiveBuilder);
|
||||||
$event->setContent($content);
|
$event->setContent($content);
|
||||||
|
|
||||||
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
|
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
|
||||||
|
|
||||||
$data = $formatter->decode($event->getContent());
|
$data = $formatter
|
||||||
|
->decode($event->getContent())
|
||||||
|
->setLang($lang)
|
||||||
|
;
|
||||||
|
|
||||||
$event->setContent(null)->setData($data);
|
$event->setContent(null)->setData($data);
|
||||||
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
|
$this->dispatch(TheliaEvents::IMPORT_AFTER_DECODE, $event);
|
||||||
@@ -385,6 +396,7 @@ class ImportController extends BaseAdminController
|
|||||||
$parserContext
|
$parserContext
|
||||||
->set("ALLOWED_MIME_TYPES", implode(",", $mimeTypes))
|
->set("ALLOWED_MIME_TYPES", implode(",", $mimeTypes))
|
||||||
->set("ALLOWED_EXTENSIONS", implode(", ", $formats))
|
->set("ALLOWED_EXTENSIONS", implode(", ", $formats))
|
||||||
|
->set("CURRENT_LANG_ID", $this->getSession()->getLang()->getId())
|
||||||
;
|
;
|
||||||
|
|
||||||
/** Then render the form */
|
/** Then render the form */
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace Thelia\Core\FileFormat\Formatting;
|
|||||||
use Propel\Runtime\ActiveQuery\ModelCriteria;
|
use Propel\Runtime\ActiveQuery\ModelCriteria;
|
||||||
use Propel\Runtime\Map\TableMap;
|
use Propel\Runtime\Map\TableMap;
|
||||||
use Thelia\Core\Translation\Translator;
|
use Thelia\Core\Translation\Translator;
|
||||||
|
use Thelia\Model\Lang;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FormatterData
|
* Class FormatterData
|
||||||
* @package Thelia\Core\FileFormat\Formatting
|
* @package Thelia\Core\FileFormat\Formatting
|
||||||
@@ -21,6 +23,8 @@ use Thelia\Core\Translation\Translator;
|
|||||||
*/
|
*/
|
||||||
class FormatterData
|
class FormatterData
|
||||||
{
|
{
|
||||||
|
protected $lang;
|
||||||
|
|
||||||
/** @var array */
|
/** @var array */
|
||||||
protected $data = array();
|
protected $data = array();
|
||||||
|
|
||||||
@@ -227,4 +231,16 @@ class FormatterData
|
|||||||
{
|
{
|
||||||
return $this->reverseAliases($this->data, $this->aliases);
|
return $this->reverseAliases($this->data, $this->aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setLang(Lang $lang)
|
||||||
|
{
|
||||||
|
$this->lang = $lang;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLang()
|
||||||
|
{
|
||||||
|
return $this->lang;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,11 @@
|
|||||||
/*************************************************************************************/
|
/*************************************************************************************/
|
||||||
|
|
||||||
namespace Thelia\Form;
|
namespace Thelia\Form;
|
||||||
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
|
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||||
use Thelia\Core\HttpFoundation\Request;
|
use Thelia\Core\HttpFoundation\Request;
|
||||||
use Thelia\Core\Translation\Translator;
|
use Thelia\Core\Translation\Translator;
|
||||||
|
use Thelia\Model\LangQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ExportForm
|
* Class ExportForm
|
||||||
@@ -58,6 +61,18 @@ class ExportForm extends BaseForm
|
|||||||
"label_attr" => ["for" => "with_documents"],
|
"label_attr" => ["for" => "with_documents"],
|
||||||
"required" => false,
|
"required" => false,
|
||||||
))
|
))
|
||||||
|
->add("language", "integer", array(
|
||||||
|
"label" => $this->translator->trans("Language"),
|
||||||
|
"label_attr" => ["for" => "language"],
|
||||||
|
"required" => true,
|
||||||
|
"constraints" => [
|
||||||
|
new Callback([
|
||||||
|
"methods" => [
|
||||||
|
[$this, "checkLanguage"],
|
||||||
|
]
|
||||||
|
])
|
||||||
|
]
|
||||||
|
))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,4 +80,19 @@ class ExportForm extends BaseForm
|
|||||||
{
|
{
|
||||||
return "thelia_export";
|
return "thelia_export";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkLanguage($value, ExecutionContextInterface $context)
|
||||||
|
{
|
||||||
|
if (null === LangQuery::create()->findPk($value)) {
|
||||||
|
$context->addViolation(
|
||||||
|
$this->translator->trans(
|
||||||
|
"The language \"%id\" doesn't exist",
|
||||||
|
[
|
||||||
|
"%id" => $value
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,11 @@
|
|||||||
/*************************************************************************************/
|
/*************************************************************************************/
|
||||||
|
|
||||||
namespace Thelia\Form;
|
namespace Thelia\Form;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Validator\Constraints\Callback;
|
||||||
|
use Symfony\Component\Validator\ExecutionContextInterface;
|
||||||
use Thelia\Core\Translation\Translator;
|
use Thelia\Core\Translation\Translator;
|
||||||
|
use Thelia\Model\LangQuery;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ImportForm
|
* Class ImportForm
|
||||||
@@ -20,6 +24,17 @@ use Thelia\Core\Translation\Translator;
|
|||||||
*/
|
*/
|
||||||
class ImportForm extends BaseForm
|
class ImportForm extends BaseForm
|
||||||
{
|
{
|
||||||
|
/** @var Translator */
|
||||||
|
protected $translator;
|
||||||
|
|
||||||
|
public function __construct(Request $request, $type = "form", $data = array(), $options = array())
|
||||||
|
{
|
||||||
|
$this->translator = Translator::getInstance();
|
||||||
|
|
||||||
|
parent::__construct($request, $type, $data, $options); // TODO: Change the autogenerated stub
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* in this function you add all the fields you need for your Form.
|
* in this function you add all the fields you need for your Form.
|
||||||
@@ -42,11 +57,25 @@ class ImportForm extends BaseForm
|
|||||||
*/
|
*/
|
||||||
protected function buildForm()
|
protected function buildForm()
|
||||||
{
|
{
|
||||||
$this->formBuilder->add("file_upload", "file", array(
|
$this->formBuilder
|
||||||
"label" => Translator::getInstance()->trans("File to upload"),
|
->add("file_upload", "file", array(
|
||||||
|
"label" => $this->translator->trans("File to upload"),
|
||||||
"label_attr" => ["for" => "file_to_upload"],
|
"label_attr" => ["for" => "file_to_upload"],
|
||||||
"required" => true,
|
"required" => true,
|
||||||
));
|
))
|
||||||
|
->add("language", "integer", array(
|
||||||
|
"label" => $this->translator->trans("Language"),
|
||||||
|
"label_attr" => ["for" => "language"],
|
||||||
|
"required" => true,
|
||||||
|
"constraints" => [
|
||||||
|
new Callback([
|
||||||
|
"methods" => [
|
||||||
|
[$this, "checkLanguage"],
|
||||||
|
]
|
||||||
|
])
|
||||||
|
]
|
||||||
|
))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,4 +86,18 @@ class ImportForm extends BaseForm
|
|||||||
return "thelia_import";
|
return "thelia_import";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkLanguage($value, ExecutionContextInterface $context)
|
||||||
|
{
|
||||||
|
if (null === LangQuery::create()->findPk($value)) {
|
||||||
|
$context->addViolation(
|
||||||
|
$this->translator->trans(
|
||||||
|
"The language \"%id\" doesn't exist",
|
||||||
|
[
|
||||||
|
"%id" => $value
|
||||||
|
]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{ifloop rel="export-formatters"}
|
{ifloop rel="export-formatters"}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-4">
|
||||||
{form_field form=$form field="formatter"}
|
{form_field form=$form field="formatter"}
|
||||||
<label for="{$label_attr.for}">
|
<label for="{$label_attr.for}">
|
||||||
{$label}
|
{$label}
|
||||||
@@ -27,7 +27,20 @@
|
|||||||
</select>
|
</select>
|
||||||
{/form_field}
|
{/form_field}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-3">
|
||||||
|
{form_field form=$form field="language"}
|
||||||
|
<label for="{$label_attr.for}">
|
||||||
|
{$label}
|
||||||
|
</label>
|
||||||
|
<select id="{$label_attr.for}" name="{$name}" required>
|
||||||
|
{loop name="export-lang" type="lang"}
|
||||||
|
<option value="{$ID}" {if $ID == $CURRENT_LANG_ID}selected{/if}>{$TITLE}</option>
|
||||||
|
{/loop}
|
||||||
|
</select>
|
||||||
|
{/form_field}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-1"></div>
|
||||||
|
<div class="col-md-4">
|
||||||
{form_field form=$form field="do_compress"}
|
{form_field form=$form field="do_compress"}
|
||||||
<label for="{$label_attr.for}">
|
<label for="{$label_attr.for}">
|
||||||
{$label}
|
{$label}
|
||||||
|
|||||||
@@ -9,14 +9,32 @@
|
|||||||
<h4 class="modal-title" id="import-modal-label">Import: {$TITLE}</h4>
|
<h4 class="modal-title" id="import-modal-label">Import: {$TITLE}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
{form_field form=$form field="file_upload"}
|
<div class="row">
|
||||||
<label form="{$label_attr.for}">
|
<div class="col-md-12">
|
||||||
{$label}
|
{form_field form=$form field="language"}
|
||||||
</label>
|
<label for="{$label_attr.for}">
|
||||||
|
{$label}
|
||||||
|
</label>
|
||||||
|
<select id="{$label_attr.for}" name="{$name}" required>
|
||||||
|
{loop name="import-lang" type="lang"}
|
||||||
|
<option value="{$ID}" {if $ID == $CURRENT_LANG_ID}selected{/if}>{$TITLE}</option>
|
||||||
|
{/loop}
|
||||||
|
</select>
|
||||||
|
{/form_field}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
{form_field form=$form field="file_upload"}
|
||||||
|
<label form="{$label_attr.for}">
|
||||||
|
{$label}
|
||||||
|
</label>
|
||||||
|
|
||||||
<input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/>
|
<input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/>
|
||||||
<div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div>
|
<div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div>
|
||||||
{/form_field}
|
{/form_field}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button>
|
<button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{ifloop rel="export-formatters"}
|
{ifloop rel="export-formatters"}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-4">
|
||||||
{form_field form=$form field="formatter"}
|
{form_field form=$form field="formatter"}
|
||||||
<div class="form-group {if $error}has-error{/if}">
|
<div class="form-group {if $error}has-error{/if}">
|
||||||
<label for="{$label_attr.for}">
|
<label for="{$label_attr.for}">
|
||||||
@@ -64,7 +64,19 @@
|
|||||||
</div>
|
</div>
|
||||||
{/form_field}
|
{/form_field}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-4">
|
||||||
|
{form_field form=$form field="language"}
|
||||||
|
<label for="{$label_attr.for}">
|
||||||
|
{$label}
|
||||||
|
</label>
|
||||||
|
<select id="{$label_attr.for}" name="{$name}" required>
|
||||||
|
{loop name="export-lang" type="lang"}
|
||||||
|
<option value="{$ID}" {if $ID == $CURRENT_LANG_ID}selected{/if}>{$TITLE}</option>
|
||||||
|
{/loop}
|
||||||
|
</select>
|
||||||
|
{/form_field}
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
{form_field form=$form field="do_compress"}
|
{form_field form=$form field="do_compress"}
|
||||||
<label for="{$label_attr.for}">
|
<label for="{$label_attr.for}">
|
||||||
{$label}
|
{$label}
|
||||||
|
|||||||
@@ -48,15 +48,32 @@
|
|||||||
|
|
||||||
<form action="{$URL}" method="post" {form_enctype form=$form}>
|
<form action="{$URL}" method="post" {form_enctype form=$form}>
|
||||||
{form_hidden_fields form=$form}
|
{form_hidden_fields form=$form}
|
||||||
{form_field form=$form field="file_upload"}
|
<div class="row">
|
||||||
<label for="{$label_attr.for}">
|
<div class="col-md-12">
|
||||||
{$label}
|
{form_field form=$form field="language"}
|
||||||
</label>
|
<label for="{$label_attr.for}">
|
||||||
|
{$label}
|
||||||
<input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/>
|
</label>
|
||||||
<div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div>
|
<select id="{$label_attr.for}" name="{$name}" required>
|
||||||
{/form_field}
|
{loop name="import-lang" type="lang"}
|
||||||
|
<option value="{$ID}" {if $ID == $CURRENT_LANG_ID}selected{/if}>{$TITLE}</option>
|
||||||
|
{/loop}
|
||||||
|
</select>
|
||||||
|
{/form_field}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
{form_field form=$form field="file_upload"}
|
||||||
|
<label form="{$label_attr.for}">
|
||||||
|
{$label}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<input type="file" required aria-required="true" name="{$name}" id="{$label_attr.for}" accept="{$ALLOWED_MIME_TYPES}"/>
|
||||||
|
<div class="small">Accepted formats: {$ALLOWED_EXTENSIONS}</div>
|
||||||
|
{/form_field}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button>
|
<button type="submit" class="btn btn-primary" title="{intl l="Import this file"}">{intl l="Import this file"}</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user