ghost
1 year ago
12 changed files with 810 additions and 6 deletions
@ -0,0 +1,181 @@
@@ -0,0 +1,181 @@
|
||||
<?php |
||||
|
||||
namespace App\Controller; |
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
||||
use Symfony\Contracts\Translation\TranslatorInterface; |
||||
|
||||
use Symfony\Component\Routing\Annotation\Route; |
||||
use Symfony\Component\HttpFoundation\Response; |
||||
use Symfony\Component\HttpFoundation\Request; |
||||
|
||||
use App\Service\UserService; |
||||
use App\Service\TorrentService; |
||||
|
||||
class TorrentController extends AbstractController |
||||
{ |
||||
#[Route( |
||||
'/{_locale}/torrent/{id}', |
||||
name: 'torrent_info', |
||||
requirements: |
||||
[ |
||||
'id' => '\d+' |
||||
], |
||||
methods: |
||||
[ |
||||
'GET' |
||||
] |
||||
)] |
||||
public function info( |
||||
Request $request, |
||||
UserService $userService, |
||||
TorrentService $torrentService |
||||
): Response |
||||
{ |
||||
// Init user |
||||
$user = $userService->init( |
||||
$request->getClientIp() |
||||
); |
||||
|
||||
return $this->render('default/torrent/info.html.twig', [ |
||||
'title' => 'test' |
||||
]); |
||||
} |
||||
|
||||
#[Route( |
||||
'/{_locale}/submit/torrent', |
||||
name: 'torrent_submit', |
||||
methods: |
||||
[ |
||||
'GET', |
||||
'POST' |
||||
] |
||||
)] |
||||
public function submit( |
||||
Request $request, |
||||
TranslatorInterface $translator, |
||||
UserService $userService, |
||||
TorrentService $torrentService |
||||
): Response |
||||
{ |
||||
// Init user |
||||
$user = $userService->init( |
||||
$request->getClientIp() |
||||
); |
||||
|
||||
if (!$user->isStatus()) |
||||
{ |
||||
// @TODO |
||||
throw new \Exception( |
||||
$translator->trans('Access denied') |
||||
); |
||||
} |
||||
|
||||
// Init form |
||||
$form = |
||||
[ |
||||
'locales' => |
||||
[ |
||||
'error' => [], |
||||
'attribute' => |
||||
[ |
||||
'value' => $request->get('locales') ? $request->get('locales') : [$request->get('_locale')], |
||||
'placeholder' => $translator->trans('Content language') |
||||
] |
||||
], |
||||
'torrent' => |
||||
[ |
||||
'error' => [], |
||||
'attribute' => |
||||
[ |
||||
'value' => null, // is local file, there is no values passed |
||||
'placeholder' => $translator->trans('Select torrent file') |
||||
] |
||||
], |
||||
'sensitive' => |
||||
[ |
||||
'error' => [], |
||||
'attribute' => |
||||
[ |
||||
'value' => $request->get('sensitive'), |
||||
'placeholder' => $translator->trans('Apply sensitive filters for this publication'), |
||||
] |
||||
] |
||||
]; |
||||
|
||||
// Process request |
||||
if ($request->isMethod('post')) |
||||
{ |
||||
/// Locales |
||||
$locales = []; |
||||
if ($request->get('locales')) |
||||
{ |
||||
foreach ((array) $request->get('locales') as $locale) |
||||
{ |
||||
if (in_array($locale, explode('|', $this->getParameter('app.locales')))) |
||||
{ |
||||
$locales[] = $locale; |
||||
} |
||||
} |
||||
} |
||||
|
||||
//// At least one valid locale required |
||||
if (!$locales) |
||||
{ |
||||
$form['locales']['error'][] = $translator->trans('At least one locale required'); |
||||
} |
||||
|
||||
/// Torrent |
||||
if ($file = $request->files->get('torrent')) |
||||
{ |
||||
//// Validate torrent file |
||||
if (filesize($file->getPathName()) > $this->getParameter('app.torrent.size.max')) |
||||
{ |
||||
$form['torrent']['error'][] = $translator->trans('Torrent file out of size limit'); |
||||
} |
||||
|
||||
if (empty($torrentService->getTorrentFilenameByFilepath($file->getPathName()))) |
||||
{ |
||||
$form['torrent']['error'][] = $translator->trans('Could not parse torrent file'); |
||||
} |
||||
} |
||||
|
||||
else |
||||
{ |
||||
$form['torrent']['error'][] = $translator->trans('Torrent file required'); |
||||
} |
||||
|
||||
// Request is valid |
||||
if (empty($form['torrent']['error']) && empty($form['locales']['error'])) |
||||
{ |
||||
// Save data |
||||
$torrent = $torrentService->submit( |
||||
$file->getPathName(), |
||||
$user->getId(), |
||||
time(), |
||||
(array) $locales, |
||||
(bool) $request->get('sensitive'), |
||||
$user->isApproved() |
||||
); |
||||
|
||||
// Redirect to info page created |
||||
return $this->redirectToRoute( |
||||
'torrent_info', |
||||
[ |
||||
'_locale' => $request->get('_locale'), |
||||
'id' => $torrent->getId() |
||||
] |
||||
); |
||||
} |
||||
} |
||||
|
||||
// Render form template |
||||
return $this->render( |
||||
'default/torrent/submit.html.twig', |
||||
[ |
||||
'locales' => explode('|', $this->getParameter('app.locales')), |
||||
'form' => $form, |
||||
] |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
<?php |
||||
|
||||
namespace App\Entity; |
||||
|
||||
use App\Repository\TorrentRepository; |
||||
use Doctrine\DBAL\Types\Types; |
||||
use Doctrine\ORM\Mapping as ORM; |
||||
|
||||
#[ORM\Entity(repositoryClass: TorrentRepository::class)] |
||||
class Torrent |
||||
{ |
||||
#[ORM\Id] |
||||
#[ORM\GeneratedValue] |
||||
#[ORM\Column] |
||||
private ?int $id = null; |
||||
|
||||
#[ORM\Column(length: 255)] |
||||
private ?string $filename = null; |
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)] |
||||
private ?string $keywords = null; |
||||
|
||||
#[ORM\Column(nullable: true)] |
||||
private ?int $seeders = null; |
||||
|
||||
#[ORM\Column(nullable: true)] |
||||
private ?int $peers = null; |
||||
|
||||
#[ORM\Column(nullable: true)] |
||||
private ?int $leechers = null; |
||||
|
||||
public function getId(): ?int |
||||
{ |
||||
return $this->id; |
||||
} |
||||
|
||||
public function setId(string $id): static |
||||
{ |
||||
$this->id = $id; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getFilename(): ?string |
||||
{ |
||||
return $this->filename; |
||||
} |
||||
|
||||
public function setFilename(string $filename): static |
||||
{ |
||||
$this->filename = $filename; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getKeywords(): ?string |
||||
{ |
||||
return $this->keywords; |
||||
} |
||||
|
||||
public function setKeywords(?string $keywords): static |
||||
{ |
||||
$this->keywords = $keywords; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getSeeders(): ?int |
||||
{ |
||||
return $this->seeders; |
||||
} |
||||
|
||||
public function setSeeders(?int $seeders): static |
||||
{ |
||||
$this->seeders = $seeders; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getPeers(): ?int |
||||
{ |
||||
return $this->peers; |
||||
} |
||||
|
||||
public function setPeers(?int $peers): static |
||||
{ |
||||
$this->peers = $peers; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getLeechers(): ?int |
||||
{ |
||||
return $this->leechers; |
||||
} |
||||
|
||||
public function setLeechers(?int $leechers): static |
||||
{ |
||||
$this->leechers = $leechers; |
||||
|
||||
return $this; |
||||
} |
||||
} |
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
<?php |
||||
|
||||
namespace App\Entity; |
||||
|
||||
use App\Repository\TorrentLocalesRepository; |
||||
use Doctrine\DBAL\Types\Types; |
||||
use Doctrine\ORM\Mapping as ORM; |
||||
|
||||
#[ORM\Entity(repositoryClass: TorrentLocalesRepository::class)] |
||||
class TorrentLocales |
||||
{ |
||||
#[ORM\Id] |
||||
#[ORM\GeneratedValue] |
||||
#[ORM\Column] |
||||
private ?int $id = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?int $torrentId = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?int $userId = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?int $added = null; |
||||
|
||||
#[ORM\Column(type: Types::ARRAY)] |
||||
private array $value = []; |
||||
|
||||
#[ORM\Column] |
||||
private ?bool $approved = null; |
||||
|
||||
public function getId(): ?int |
||||
{ |
||||
return $this->id; |
||||
} |
||||
|
||||
public function setId(string $id): static |
||||
{ |
||||
$this->id = $id; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getTorrentId(): ?int |
||||
{ |
||||
return $this->torrentId; |
||||
} |
||||
|
||||
public function setTorrentId(int $torrentId): static |
||||
{ |
||||
$this->torrentId = $torrentId; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getUserId(): ?int |
||||
{ |
||||
return $this->userId; |
||||
} |
||||
|
||||
public function setUserId(int $userId): static |
||||
{ |
||||
$this->userId = $userId; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getAdded(): ?int |
||||
{ |
||||
return $this->added; |
||||
} |
||||
|
||||
public function setAdded(int $added): static |
||||
{ |
||||
$this->added = $added; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getValue(): array |
||||
{ |
||||
return $this->value; |
||||
} |
||||
|
||||
public function setValue(array $value): static |
||||
{ |
||||
$this->value = $value; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function isApproved(): ?bool |
||||
{ |
||||
return $this->approved; |
||||
} |
||||
|
||||
public function setApproved(bool $approved): static |
||||
{ |
||||
$this->approved = $approved; |
||||
|
||||
return $this; |
||||
} |
||||
} |
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
<?php |
||||
|
||||
namespace App\Entity; |
||||
|
||||
use App\Repository\TorrentSensitiveRepository; |
||||
use Doctrine\DBAL\Types\Types; |
||||
use Doctrine\ORM\Mapping as ORM; |
||||
|
||||
#[ORM\Entity(repositoryClass: TorrentSensitiveRepository::class)] |
||||
class TorrentSensitive |
||||
{ |
||||
#[ORM\Id] |
||||
#[ORM\GeneratedValue] |
||||
#[ORM\Column] |
||||
private ?int $id = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?int $torrentId = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?int $userId = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?int $added = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?bool $value = null; |
||||
|
||||
#[ORM\Column] |
||||
private ?bool $approved = null; |
||||
|
||||
public function getId(): ?int |
||||
{ |
||||
return $this->id; |
||||
} |
||||
|
||||
public function setId(string $id): static |
||||
{ |
||||
$this->id = $id; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getTorrentId(): ?int |
||||
{ |
||||
return $this->torrentId; |
||||
} |
||||
|
||||
public function setTorrentId(int $torrentId): static |
||||
{ |
||||
$this->torrentId = $torrentId; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getUserId(): ?int |
||||
{ |
||||
return $this->userId; |
||||
} |
||||
|
||||
public function setUserId(int $userId): static |
||||
{ |
||||
$this->userId = $userId; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function getAdded(): ?int |
||||
{ |
||||
return $this->added; |
||||
} |
||||
|
||||
public function setAdded(int $added): static |
||||
{ |
||||
$this->added = $added; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function isValue(): ?bool |
||||
{ |
||||
return $this->value; |
||||
} |
||||
|
||||
public function setValue(bool $value): static |
||||
{ |
||||
$this->value = $value; |
||||
|
||||
return $this; |
||||
} |
||||
|
||||
public function isApproved(): ?bool |
||||
{ |
||||
return $this->approved; |
||||
} |
||||
|
||||
public function setApproved(bool $approved): static |
||||
{ |
||||
$this->approved = $approved; |
||||
|
||||
return $this; |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
<?php |
||||
|
||||
namespace App\Repository; |
||||
|
||||
use App\Entity\TorrentLocales; |
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
|
||||
/** |
||||
* @extends ServiceEntityRepository<TorrentLocales> |
||||
* |
||||
* @method TorrentLocales|null find($id, $lockMode = null, $lockVersion = null) |
||||
* @method TorrentLocales|null findOneBy(array $criteria, array $orderBy = null) |
||||
* @method TorrentLocales[] findAll() |
||||
* @method TorrentLocales[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) |
||||
*/ |
||||
class TorrentLocalesRepository extends ServiceEntityRepository |
||||
{ |
||||
public function __construct(ManagerRegistry $registry) |
||||
{ |
||||
parent::__construct($registry, TorrentLocales::class); |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
<?php |
||||
|
||||
namespace App\Repository; |
||||
|
||||
use App\Entity\Torrent; |
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
|
||||
/** |
||||
* @extends ServiceEntityRepository<Torrent> |
||||
* |
||||
* @method Torrent|null find($id, $lockMode = null, $lockVersion = null) |
||||
* @method Torrent|null findOneBy(array $criteria, array $orderBy = null) |
||||
* @method Torrent[] findAll() |
||||
* @method Torrent[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) |
||||
*/ |
||||
class TorrentRepository extends ServiceEntityRepository |
||||
{ |
||||
public function __construct(ManagerRegistry $registry) |
||||
{ |
||||
parent::__construct($registry, Torrent::class); |
||||
} |
||||
} |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
<?php |
||||
|
||||
namespace App\Repository; |
||||
|
||||
use App\Entity\TorrentSensitive; |
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; |
||||
use Doctrine\Persistence\ManagerRegistry; |
||||
|
||||
/** |
||||
* @extends ServiceEntityRepository<TorrentSensitive> |
||||
* |
||||
* @method TorrentSensitive|null find($id, $lockMode = null, $lockVersion = null) |
||||
* @method TorrentSensitive|null findOneBy(array $criteria, array $orderBy = null) |
||||
* @method TorrentSensitive[] findAll() |
||||
* @method TorrentSensitive[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) |
||||
*/ |
||||
class TorrentSensitiveRepository extends ServiceEntityRepository |
||||
{ |
||||
public function __construct(ManagerRegistry $registry) |
||||
{ |
||||
parent::__construct($registry, TorrentSensitive::class); |
||||
} |
||||
} |
@ -0,0 +1,163 @@
@@ -0,0 +1,163 @@
|
||||
<?php |
||||
|
||||
namespace App\Service; |
||||
|
||||
use App\Entity\Torrent; |
||||
use App\Entity\TorrentLocales; |
||||
use App\Entity\TorrentSensitive; |
||||
|
||||
use App\Repository\TorrentRepository; |
||||
use App\Repository\TorrentLocalesRepository; |
||||
use App\Repository\TorrentSensitiveRepository; |
||||
|
||||
use Doctrine\ORM\EntityManagerInterface; |
||||
|
||||
class TorrentService |
||||
{ |
||||
private EntityManagerInterface $entityManager; |
||||
private ParameterBagInterface $parameterBagInterface; |
||||
|
||||
public function __construct( |
||||
EntityManagerInterface $entityManager, |
||||
) |
||||
{ |
||||
$this->entityManager = $entityManager; |
||||
} |
||||
|
||||
public function decodeTorrentByFilepath(string $filepath): array |
||||
{ |
||||
$decoder = new \BitTorrent\Decoder(); |
||||
|
||||
return $decoder->decodeFile($filepath); |
||||
} |
||||
|
||||
public function getTorrentFilenameByFilepath(string $filepath): string |
||||
{ |
||||
$data = $this->decodeTorrentByFilepath($filepath); |
||||
|
||||
if (!empty($data['info']['name'])) |
||||
{ |
||||
return $data['info']['name']; |
||||
} |
||||
|
||||
return $data['info']['name']; |
||||
} |
||||
|
||||
public function getTorrentKeywordsByFilepath(string $filepath): string |
||||
{ |
||||
$data = $this->decodeTorrentByFilepath($filepath); |
||||
|
||||
if (!empty($data['info']['name'])) |
||||
{ |
||||
return mb_strtolower( |
||||
preg_replace( |
||||
'/[\s]+/', |
||||
' ', |
||||
preg_replace( |
||||
'/[\W]+/', |
||||
' ', |
||||
$data['info']['name'] |
||||
) |
||||
) |
||||
); |
||||
} |
||||
|
||||
return ''; |
||||
} |
||||
|
||||
public function submit( |
||||
string $filepath, |
||||
int $userId, |
||||
int $added, |
||||
array $locales, |
||||
bool $sensitive, |
||||
bool $approved |
||||
): ?Torrent |
||||
{ |
||||
$torrent = $this->saveTorrent( |
||||
$this->getTorrentFilenameByFilepath($filepath), |
||||
$this->getTorrentKeywordsByFilepath($filepath) |
||||
); |
||||
|
||||
if (!empty($locales)) |
||||
{ |
||||
$this->saveTorrentLocales( |
||||
$torrent->getId(), |
||||
$userId, |
||||
$added, |
||||
$locales, |
||||
$approved |
||||
); |
||||
} |
||||
|
||||
$this->saveTorrentSensitive( |
||||
$torrent->getId(), |
||||
$userId, |
||||
$added, |
||||
$sensitive, |
||||
$approved |
||||
); |
||||
|
||||
return $torrent; |
||||
} |
||||
|
||||
public function saveTorrent( |
||||
string $filepath, |
||||
string $keywords |
||||
): ?Torrent |
||||
{ |
||||
$torrent = new Torrent(); |
||||
|
||||
$torrent->setFilename($filepath); |
||||
$torrent->setKeywords($keywords); |
||||
|
||||
$this->entityManager->persist($torrent); |
||||
$this->entityManager->flush(); |
||||
|
||||
return $torrent; |
||||
} |
||||
|
||||
public function saveTorrentLocales( |
||||
int $torrentId, |
||||
int $userId, |
||||
int $added, |
||||
array $value, |
||||
bool $approved |
||||
): ?TorrentLocales |
||||
{ |
||||
$torrentLocales = new TorrentLocales(); |
||||
|
||||
$torrentLocales->setTorrentId($torrentId); |
||||
$torrentLocales->setUserId($userId); |
||||
$torrentLocales->setAdded($added); |
||||
$torrentLocales->setValue($value); |
||||
$torrentLocales->setApproved($approved); |
||||
|
||||
$this->entityManager->persist($torrentLocales); |
||||
$this->entityManager->flush(); |
||||
|
||||
return $torrentLocales; |
||||
} |
||||
|
||||
public function saveTorrentSensitive( |
||||
int $torrentId, |
||||
int $userId, |
||||
int $added, |
||||
bool $value, |
||||
bool $approved |
||||
): ?TorrentSensitive |
||||
{ |
||||
$torrentSensitive = new TorrentSensitive(); |
||||
|
||||
$torrentSensitive->setTorrentId($torrentId); |
||||
$torrentSensitive->setUserId($userId); |
||||
$torrentSensitive->setAdded($added); |
||||
$torrentSensitive->setValue($value); |
||||
$torrentSensitive->setApproved($approved); |
||||
|
||||
$this->entityManager->persist($torrentSensitive); |
||||
$this->entityManager->flush(); |
||||
|
||||
return $torrentSensitive; |
||||
} |
||||
} |
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
{% extends 'default/layout.html.twig' %} |
||||
{% block title %}{{ title }} - {{ name }}{% endblock %} |
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
{% extends 'default/layout.html.twig' %} |
||||
{% block title %}{{'Submit torrent'|trans }} - {{ name }}{% endblock %} |
||||
{% block main_content %} |
||||
<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 torrent'|trans }}</h1> |
||||
</div> |
||||
<form name="submit" method="post" enctype="multipart/form-data" action="{{ path('torrent_submit') }}"> |
||||
<div class="margin-y-16-px"> |
||||
<label for="torrent"> |
||||
{{'Torrent file'|trans }} |
||||
</label> |
||||
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.torrent.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.torrent.error %} |
||||
<div class="text-color-red margin-y-8-px"> |
||||
{{ error }} |
||||
</div> |
||||
{% endfor %} |
||||
<input class="width-100 margin-t-8-px" type="file" name="torrent" id="torrent" value="" accept=".torrent" /> |
||||
</div> |
||||
<div class="margin-y-16-px"> |
||||
<label for="locales"> |
||||
{{'Content language'|trans }} |
||||
</label> |
||||
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.locales.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.locales.error %} |
||||
<div class="text-color-red margin-y-8-px"> |
||||
{{ error }} |
||||
</div> |
||||
{% endfor %} |
||||
<div class="padding-t-8-px"> |
||||
<select class="width-100 padding-x-0" name="locales[]" multiple="multiple"> |
||||
{% for locale in locales %} |
||||
{% if locale in form.locales.attribute.value %} |
||||
<option class="padding-x-8-px padding-y-8-px" value="{{ locale }}" selected="selected"> |
||||
{{ locale|locale_name(locale)|u.title }} |
||||
</option> |
||||
{% else %} |
||||
<option class="padding-x-8-px padding-y-8-px" value="{{ locale }}"> |
||||
{{ locale|locale_name(locale)|u.title }} |
||||
</option> |
||||
{% endif %} |
||||
{% endfor %} |
||||
{# |
||||
<option class="padding-x-8-px padding-y-8-px" value="other"> |
||||
{{'Other...'|trans }} |
||||
</option> |
||||
#} |
||||
</select> |
||||
</div> |
||||
</div> |
||||
<div class="margin-y-16-px"> |
||||
<input type="checkbox" |
||||
name="sensitive" |
||||
id="sensitive" |
||||
value="true" |
||||
{% if form.sensitive.attribute.value %}checked="checked"{% endif %} /> |
||||
<label for="sensitive"> |
||||
{{'Sensitive'|trans }} |
||||
</label> |
||||
<sub class="opacity-0 parent-hover-opacity-09" title="{{ form.sensitive.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> |
||||
</div> |
||||
<div class="text-right"> |
||||
<input class="button-green" type="submit" value="{{'Submit'|trans }}" /> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
{% endblock %} |
Loading…
Reference in new issue