Browse Source

draft submit form #14

main
ghost 1 year ago
parent
commit
731624d886
  1. 8
      .env
  2. 8
      config/services.yaml
  3. 185
      src/Controller/PageController.php
  4. 37
      src/Service/PageService.php
  5. 208
      templates/default/page/submit.html.twig

8
.env

@ -51,3 +51,11 @@ APP_NAME=YGGtracker
APP_LOCALE=en APP_LOCALE=en
APP_LOCALES=de|fr|en|uk APP_LOCALES=de|fr|en|uk
APP_PAGE_TITLE_LENGTH_MIN=10
APP_PAGE_TITLE_LENGTH_MAX=255
APP_PAGE_DESCRIPTION_LENGTH_MIN=0
APP_PAGE_DESCRIPTION_LENGTH_MAX=10000
APP_PAGE_TORRENT_QUANTITY_MIN=1
APP_PAGE_TORRENT_QUANTITY_MAX=100
APP_PAGE_TORRENT_SIZE_MAX=1024000

8
config/services.yaml

@ -8,6 +8,14 @@ parameters:
app.name: '%env(APP_NAME)%' app.name: '%env(APP_NAME)%'
app.locale: '%env(APP_LOCALE)%' app.locale: '%env(APP_LOCALE)%'
app.locales: '%env(APP_LOCALES)%' app.locales: '%env(APP_LOCALES)%'
app.page.title.length.min: '%env(APP_PAGE_TITLE_LENGTH_MIN)%'
app.page.title.length.max: '%env(APP_PAGE_TITLE_LENGTH_MAX)%'
app.page.description.length.min: '%env(APP_PAGE_DESCRIPTION_LENGTH_MIN)%'
app.page.description.length.max: '%env(APP_PAGE_DESCRIPTION_LENGTH_MAX)%'
app.page.torrent.quantity.min: '%env(APP_PAGE_TORRENT_QUANTITY_MIN)%'
app.page.torrent.quantity.max: '%env(APP_PAGE_TORRENT_QUANTITY_MAX)%'
app.page.torrent.size.min: '%env(APP_PAGE_TORRENT_SIZE_MIN)%'
app.page.torrent.size.max: '%env(APP_PAGE_TORRENT_SIZE_MAX)%'
services: services:
# default configuration for services in *this* file # default configuration for services in *this* file

185
src/Controller/PageController.php

@ -3,25 +3,196 @@
namespace App\Controller; namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use App\Service\UserService;
use App\Service\PageService;
use App\Service\TimeService;
class PageController extends AbstractController class PageController extends AbstractController
{ {
#[Route( #[Route(
'/{_locale}/page/submit', '/{_locale}/page/submit',
name: 'page_submit' name: 'page_submit'
)] )]
public function submit(): Response public function submit(
Request $request,
TranslatorInterface $translator,
UserService $userService,
PageService $pageService,
): Response
{ {
/* // Init user
return $this->redirectToRoute('page', [ $user = $userService->init(
'id' => $page->getId() $request->getClientIp()
]); );
*/
return $this->render('default/page/submit.html.twig', [ if (!$user->isStatus())
{
// @TODO // @TODO
throw new \Exception(
$translator->trans('Access denied')
);
}
// Init form
$form =
[
'locale' =>
[
'error' => [],
'value' => $request->get('_locale'),
'placeholder' => $translator->trans('Content language'),
],
'title' =>
[
'error' => [],
'attribute' =>
[
'value' => $request->get('title'),
'minlength' => $this->getParameter('app.page.title.length.min'),
'maxlength' => $this->getParameter('app.page.title.length.max'),
'placeholder' => sprintf(
$translator->trans('Page title text (%s-%s chars)'),
number_format($this->getParameter('app.page.title.length.min')),
number_format($this->getParameter('app.page.title.length.max'))
),
]
],
'description' =>
[
'error' => [],
'attribute' =>
[
'value' => $request->get('description'),
'minlength' => $this->getParameter('app.page.description.length.min'),
'maxlength' => $this->getParameter('app.page.description.length.max'),
'placeholder' => sprintf(
$translator->trans('Page description text (%s-%s chars)'),
number_format($this->getParameter('app.page.description.length.min')),
number_format($this->getParameter('app.page.description.length.max'))
),
]
],
'torrents' =>
[
'error' => [],
'attribute' =>
[
'placeholder' => $translator->trans('Select torrent files'),
]
],
'sensitive' =>
[
'error' => [],
'attribute' =>
[
'value' => $request->get('sensitive'),
'placeholder' => $translator->trans('Apply sensitive filters for this publication'),
]
]
];
// Process request
if ($request->isMethod('post'))
{
// Init new
$page = $pageService->new();
/// Locale
if (!in_array($request->get('locale'), explode('|', $this->getParameter('app.locales'))))
{
$form['locale']['error'][] = $translator->trans('Requested locale not supported');
}
else
{
// $request->get('locale')
}
/// Title
if (mb_strlen($request->get('title')) < $this->getParameter('app.page.title.length.min') ||
mb_strlen($request->get('title')) > $this->getParameter('app.page.title.length.max'))
{
$form['title']['error'][] = sprintf(
$translator->trans('Page title out of %s-%s chars'),
number_format($this->getParameter('app.page.title.length.min')),
number_format($this->getParameter('app.page.title.length.max'))
);
}
else
{
// $request->get('title')
}
/// Description
if (mb_strlen($request->get('description')) < $this->getParameter('app.page.description.length.min') ||
mb_strlen($request->get('description')) > $this->getParameter('app.page.description.length.max'))
{
$form['description']['error'][] = sprintf(
$translator->trans('Page description out of %s-%s chars'),
number_format($this->getParameter('app.page.description.length.min')),
number_format($this->getParameter('app.page.description.length.max'))
);
}
else
{
// $request->get('description')
}
/// Torrents
$total = 0;
if ($files = $request->files->get('torrents'))
{
foreach ($files as $file)
{
//// Quantity
$total++;
//// File size
if (filesize($file->getPathName()) > $this->getParameter('app.page.torrent.size.max'))
{
$form['torrents']['error'][] = $translator->trans('Torrent file out of size limit');
}
//// Content
$decoder = new \BitTorrent\Decoder();
$decodedFile = $decoder->decodeFile(
$file->getPathName()
);
// var_dump($decodedFile['info']['name']);
}
}
if ($total < $this->getParameter('app.page.torrent.quantity.min') ||
$total > $this->getParameter('app.page.torrent.quantity.max'))
{
$form['torrents']['error'][] = sprintf(
$translator->trans('Torrents quantity out of %s-%s range'),
number_format($this->getParameter('app.page.torrent.quantity.min')),
number_format($this->getParameter('app.page.torrent.quantity.max'))
);
}
if (empty($error))
{
// isset($request->get('sensitive'))
// $pageService->save($page);
}
}
return $this->render('default/page/submit.html.twig', [
'locales' => explode('|', $this->getParameter('app.locales')),
'form' => $form,
]); ]);
} }
} }

37
src/Service/PageService.php

@ -0,0 +1,37 @@
<?php
namespace App\Service;
use App\Entity\Page;
use App\Repository\PageRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
class PageService
{
private EntityManagerInterface $entityManager;
private PageRepository $pageRepository;
private ParameterBagInterface $parameterBagInterface;
public function __construct(
EntityManagerInterface $entityManager,
ParameterBagInterface $parameterBagInterface
)
{
$this->entityManager = $entityManager;
$this->pageRepository = $entityManager->getRepository(Page::class);
$this->parameterBagInterface = $parameterBagInterface;
}
public function new(): ?Page
{
return new Page();
}
public function save(Page $page) : void
{
$this->entityManager->persist($page);
$this->entityManager->flush();
}
}

208
templates/default/page/submit.html.twig

@ -1,129 +1,115 @@
{% extends 'default/layout.html.twig' %} {% extends 'default/layout.html.twig' %}
{% block title %}{{'Submit'|trans }} - {{ name }}{% endblock %} {% block title %}{{'Submit'|trans }} - {{ name }}{% endblock %}
{% block main_content %} {% block main_content %}
<div class="margin-b-24-px padding-b-16-px border-bottom-default"> <div class="padding-24-px margin-y-8-px border-radius-3-px background-color-night">
<div class="margin-b-24-px padding-b-16-px border-bottom-default">
<h1>{{'Submit'|trans }}</h1> <h1>{{'Submit'|trans }}</h1>
</div>
<form class="margin-t-8-px" name="submit" method="post" enctype="multipart/form-data" action="submit">
<input type="hidden" name="pageId" value="<?php echo $form->pageId->attribute->value ?>" />
<div class="margin-b-16">
<label for="locale">
{{'Content language'|trans }}
</label>
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.locale.placeholder }}">
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</svg>
</sub>
<select class="width-100 margin-t-8" type="text" name="locale" id="locale">
{% for locale in form.locale.options %}
{% if locale.active %}
<option value="{{ locale.code }}" selected="selected">
{{ locale.value }}
</option>
{% else %}
<option value="{{ locale.code }}">
{{ locale.value }}
</option>
{% endif %}
{% endfor %}
</select>
</div> </div>
<div class="margin-b-16"> <form name="submit" method="post" enctype="multipart/form-data" action="{{ path('page_submit') }}">
<label for="title"> <div class="margin-b-16-px">
{{'Title'|trans }} <label for="locale">
</label> {{'Content language'|trans }}
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.title.attribute.placeholder }}"> </label>
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16"> <sub class="opacity-0 parent-hover-opacity-09" title="{{ form.locale.placeholder }}">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16">
</svg> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</sub> </svg>
{% for errors in form.title.error %} </sub>
{% for error in errors %} <select class="width-100 margin-t-8-px" type="text" name="locale" id="locale">
{% for locale in locales %}
{% if locale == form.locale.value %}
<option value="{{ locale }}" selected="selected">
{{ locale|locale_name(locale)|u.title }}
</option>
{% else %}
<option value="{{ locale }}">
{{ locale|locale_name(locale)|u.title }}
</option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="margin-b-16-px">
<label for="title">
{{'Title'|trans }}
</label>
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.title.attribute.placeholder }}">
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</svg>
</sub>
{% for error in form.title.error %}
<div class="text-color-red margin-y-8-px"> <div class="text-color-red margin-y-8-px">
{{ error }} {{ error }}
</div> </div>
{% endfor %} {% endfor %}
{% endfor %} <input class="width-100 margin-t-8-px"
<input class="width-100 margin-t-8-px" type="text"
type="text" name="title"
name="title" id="title"
id="title" {% if form.title.attribute.minlength %}required="required"{% endif %}
{% if form.title.attribute.required %}required="required"{% endif %} value="{{ form.title.attribute.value }}"
value="{{ form.title.attribute.value }}" placeholder="{{ form.title.attribute.placeholder }}"
placeholder="{{ form.title.attribute.placeholder }}" minlength="{{ form.title.attribute.minlength }}"
minlength="{{ form.title.attribute.minlength }}" maxlength="{{ form.title.attribute.maxlength }}" />
maxlength="{{ form.title.attribute.maxlength }}" /> </div>
</div> <div class="margin-y-8-px">
<div class="margin-y-8-px padding-t-4-px"> <label for="description">
<label for="description"> {{'Description'|trans }}
{{'Description'|trans }} </label>
</label> <sub class="opacity-0 parent-hover-opacity-09" title="{{ form.description.attribute.placeholder }}">
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.description.attribute.placeholder }}"> <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16"> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> </svg>
</svg> </sub>
</sub> {% for error in form.description.error %}
{% for errors in form.description.error %}
{% for error in errors %}
<div class="text-color-red margin-y-8-px"> <div class="text-color-red margin-y-8-px">
{{ error }} {{ error }}
</div> </div>
{% endfor %} {% endfor %}
{% endfor %} <textarea class="width-100 margin-t-8-px"
<textarea class="width-100 margin-t-8-px" name="description"
name="description" id="description"
id="description" {% if form.description.attribute.minlength %}required="required"{% endif %}
{% if form.description.attribute.required %}required="required"{% endif %} value="{{ form.description.attribute.value }}"
value="{{ form.description.attribute.value }}" placeholder="{{ form.description.attribute.placeholder }}"
placeholder="{{ form.description.attribute.placeholder }}" minlength="{{ form.description.attribute.minlength }}"
minlength="{{ form.description.attribute.minlength }}" maxlength="{{ form.description.attribute.maxlength }}">{{ form.description.attribute.value }}</textarea>
maxlength="{{ form.description.attribute.maxlength }}">{{ form.description.attribute.value }}</textarea> </div>
</div> <div class="margin-y-16-px">
<div class="margin-y-8 padding-t-4"> <label for="torrents">
<label for="keywords"> {{'Torrent files'|trans }}
{{'Keywords'|trans }} </label>
</label> <sub class="opacity-0 parent-hover-opacity-09" title="{{ form.torrents.attribute.placeholder }}">
<sub class="opacity-0 parent-hover-opacity-09" <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
title="<?php echo $form->keywords->attribute->placeholder ?>"> <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16"> </svg>
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> </sub>
</svg> {% for error in form.torrents.error %}
</sub>
{% for errors in form.keywords.error %}
{% for error in errors %}
<div class="text-color-red margin-y-8-px"> <div class="text-color-red margin-y-8-px">
{{ error }} {{ error }}
</div> </div>
{% endfor %} {% endfor %}
{% endfor %} <input class="width-100 margin-t-8-px" type="file" name="torrents[]" id="torrents" value="" accept=".torrent" multiple="multiple" />
<textarea class="width-100 margin-t-8-px" </div>
name="keywords" <div class="margin-y-16-px">
id="keywords" <input type="checkbox"
{% if form.keywords.attribute.required %}required="required"{% endif %} name="sensitive"
value="{{ form.keywords.attribute.value }}" id="sensitive"
placeholder="{{ form.keywords.attribute.placeholder }}" value="true"
minlength="{{ form.keywords.attribute.minlength }}" {% if form.sensitive.attribute.value %}checked="checked"{% endif %} />
maxlength="{{ form.keywords.attribute.maxlength }}">{{ form.keywords.attribute.value }}</textarea> <label for="sensitive">
</div> {{'Sensitive'|trans }}
<div class="margin-y-16-px"> </label>
<input type="checkbox" <sub class="opacity-0 parent-hover-opacity-09" title="{{ form.sensitive.attribute.placeholder }}">
name="sensitive" <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" viewBox="0 0 16 16">
id="sensitive" <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
value="true" </svg>
{% form.sensitive.attribute.value %}checked="checked"{% endif %} /> </sub>
<label for="sensitive"> </div>
{{'Sensitive'|trans }} <div class="text-right">
</label> <input class="button-green" type="submit" value="{{'Submit'|trans }}" />
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.sensitive.attribute.placeholder }}"> </div>
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" fill="currentColor" class="bi bi-info-circle-fill" viewBox="0 0 16 16"> </form>
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/> </div>
</svg>
</sub>
</div>
<div class="text-right">
<input class="button-green" type="submit" value="{{'Submit'|trans }}" />
</div>
</form>
{% endblock %} {% endblock %}

Loading…
Cancel
Save