Browse Source

Merge branch 'develop' of https://forge.laclic.fr/Laclic/SovBundle into develop

feature/symfony6.1
Charly 3 years ago
parent
commit
230c24b41d
16 changed files with 364 additions and 14 deletions
  1. +5
    -1
      Authenticator/LoginFormAuthenticator.php
  2. +3
    -0
      Component/FileComponent.php
  3. +1
    -0
      Container/ComponentContainer.php
  4. +7
    -0
      Controller/ControllerTrait.php
  5. +2
    -2
      Definition/Field/Site/PageFieldDefinition.php
  6. +0
    -1
      Form/Common/FileManagerType.php
  7. +258
    -0
      Form/Common/FileUploadType.php
  8. +14
    -0
      Repository/AbstractRepositoryQuery.php
  9. +1
    -2
      Repository/User/GroupUserRepositoryQuery.php
  10. +45
    -1
      Resolver/UrlResolver.php
  11. +3
    -2
      Resources/assets/app/adminlte/main/init.js
  12. +7
    -3
      Resources/assets/functions/widgets.js
  13. +1
    -0
      Resources/config/services.yaml
  14. +1
    -0
      Resources/translations/admin.fr.yaml
  15. +0
    -1
      Resources/views/adminlte/crud/form_theme.html.twig
  16. +16
    -1
      Twig/TwigExtension.php

+ 5
- 1
Authenticator/LoginFormAuthenticator.php View File

use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
return $this->userStore->getOneByEmail($userIdentifier); return $this->userStore->getOneByEmail($userIdentifier);
}), }),
new PasswordCredentials($password), new PasswordCredentials($password),
[new CsrfTokenBadge('authenticate', $csrfToken)]
[
new CsrfTokenBadge('authenticate', $csrfToken),
new RememberMeBadge()
]
); );
} }



+ 3
- 0
Component/FileComponent.php View File

$path = substr($path, 1); $path = substr($path, 1);
} }


// gestion des accents et des espaces
$path = urldecode($path);

if ($path) { if ($path) {


$fileManagerFolder = substr($this->getFileManagerFolder(), 1); $fileManagerFolder = substr($this->getFileManagerFolder(), 1);

+ 1
- 0
Container/ComponentContainer.php View File



namespace Lc\SovBundle\Container; namespace Lc\SovBundle\Container;


use Lc\SovBundle\Component\ArrayComponent;
use Lc\SovBundle\Component\CitiesComponent; use Lc\SovBundle\Component\CitiesComponent;
use Lc\SovBundle\Component\CookieComponent; use Lc\SovBundle\Component\CookieComponent;
use Lc\SovBundle\Component\DateComponent; use Lc\SovBundle\Component\DateComponent;

+ 7
- 0
Controller/ControllerTrait.php View File

use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment; use Twig\Environment;


return $this->get(SiteSettingContainer::class); return $this->get(SiteSettingContainer::class);
} }


public function setNoMemoryAndTimeLimit(): void
{
ini_set('memory_limit', '-1');
set_time_limit(0);
}

} }

+ 2
- 2
Definition/Field/Site/PageFieldDefinition.php View File

]; ];
} }


public function configurePanelMain(): array
public function configurePanelGeneral(): array
{ {
return [ return [
'title', 'title',


public function configurePanels(): array public function configurePanels(): array
{ {
return ['main', 'seo', 'conf'];
return ['general', 'seo', 'conf'];
} }


public function configureFields(): array public function configureFields(): array

+ 0
- 1
Form/Common/FileManagerType.php View File

$this->em = $entityManager; $this->em = $entityManager;
} }



public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$builder->add('path', HiddenType::class, array( $builder->add('path', HiddenType::class, array(

+ 258
- 0
Form/Common/FileUploadType.php View File

<?php

namespace Lc\SovBundle\Form\Common;

use EasyCorp\Bundle\EasyAdminBundle\Form\DataTransformer\StringToFileTransformer;
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\Model\FileUploadState;
use Lc\SovBundle\Model\File\FileInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\File\File;
use Lc\SovBundle\Doctrine\EntityManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\OptionsResolver\Exception\InvalidArgumentException;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\String\Slugger\AsciiSlugger;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;

class FileUploadType extends AbstractType implements DataMapperInterface, DataTransformerInterface
{
protected string $projectDir;
protected EntityManager $entityManager;

public function __construct(EntityManager $entityManager, ParameterBagInterface $parameterBag)
{
$this->projectDir = $parameterBag->get('kernel.project_dir');
$this->entityManager = $entityManager;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
$uploadDir = $options['upload_dir'];
$uploadFilename = $options['upload_filename'];
$uploadValidate = $options['upload_validate'];
$allowAdd = $options['allow_add'];
unset($options['upload_dir'], $options['upload_new'], $options['upload_delete'], $options['upload_filename'], $options['upload_validate'], $options['download_path'], $options['allow_add'], $options['allow_delete'], $options['compound']);

$builder->add('path', FileType::class, $options);
$builder->add('legend', TextType::class, array(
'attr' => [
"placeholder" => 'Légende'
],
'label' => false
));
$builder->add('delete', CheckboxType::class, ['required' => false, 'mapped' => false]);

$builder->setDataMapper($this);
$builder->setAttribute('state', new FileUploadState($allowAdd));
$builder->addModelTransformer(new StringToFileTransformer($uploadDir, $uploadFilename, $uploadValidate, $options['multiple']));

/*
$builder->add('path', FileType::class, array(
'block_prefix' => 'file_manager_image',
'label' => false
));

$builder->add('legend', TextType::class, array(
'block_prefix' => 'file_upload_legend',
'attr' => array(
"placeholder" => 'Légende'
),
'label' => false
));

$builder->add('position', HiddenType::class, array(
'block_prefix' => 'file_upload_position',
'empty_data' => 0,
'required' => true,
'attr' => array(
'class' => 'field-position'
),
'label' => false
));
*/
}

/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver): void
{
$uploadNew = static function (UploadedFile $file, string $uploadDir, string $fileName) {
$file->move($uploadDir, $fileName);
};

$uploadDelete = static function (File $file) {
unlink($file->getPathname());
};

$uploadFilename = static function (UploadedFile $file): string {
return $file->getClientOriginalName();
};

$uploadValidate = static function (string $filename): string {
if (!file_exists($filename)) {
return $filename;
}

$index = 1;
$pathInfo = pathinfo($filename);
while (file_exists($filename = sprintf('%s/%s_%d.%s', $pathInfo['dirname'], $pathInfo['filename'], $index, $pathInfo['extension']))) {
++$index;
}

return $filename;
};

$downloadPath = function (Options $options) {
return mb_substr($options['upload_dir'], mb_strlen($this->projectDir.'/public/'));
};

$allowAdd = static function (Options $options) {
return $options['multiple'];
};

$dataClass = static function (Options $options) {
return $options['multiple'] ? null : File::class;
};

$emptyData = static function (Options $options) {
return $options['multiple'] ? [] : null;
};

$resolver->setDefaults([
'upload_dir' => $this->projectDir.'/public/uploads/files/',
'upload_new' => $uploadNew,
'upload_delete' => $uploadDelete,
'upload_filename' => $uploadFilename,
'upload_validate' => $uploadValidate,
'download_path' => $downloadPath,
'allow_add' => $allowAdd,
'allow_delete' => true,
//'data_class' => $dataClass,
'data_class' => $this->entityManager->getEntityName(FileInterface::class),
'empty_data' => $emptyData,
'multiple' => false,
'required' => false,
'error_bubbling' => false,
'allow_file_upload' => true,
]);

$resolver->setAllowedTypes('upload_dir', 'string');
$resolver->setAllowedTypes('upload_new', 'callable');
$resolver->setAllowedTypes('upload_delete', 'callable');
$resolver->setAllowedTypes('upload_filename', ['string', 'callable']);
$resolver->setAllowedTypes('upload_validate', 'callable');
$resolver->setAllowedTypes('download_path', ['null', 'string']);
$resolver->setAllowedTypes('allow_add', 'bool');
$resolver->setAllowedTypes('allow_delete', 'bool');

$resolver->setNormalizer('upload_dir', function (Options $options, string $value): string {
if (\DIRECTORY_SEPARATOR !== mb_substr($value, -1)) {
$value .= \DIRECTORY_SEPARATOR;
}

if (0 !== mb_strpos($value, $this->projectDir)) {
$value = $this->projectDir.'/'.$value;
}

if ('' !== $value && (!is_dir($value) || !is_writable($value))) {
throw new InvalidArgumentException(sprintf('Invalid upload directory "%s" it does not exist or is not writable.', $value));
}

return $value;
});
$resolver->setNormalizer('upload_filename', static function (Options $options, $fileNamePatternOrCallable) {
if (\is_callable($fileNamePatternOrCallable)) {
return $fileNamePatternOrCallable;
}

return static function (UploadedFile $file) use ($fileNamePatternOrCallable) {
return strtr($fileNamePatternOrCallable, [
'[contenthash]' => sha1_file($file->getRealPath()),
'[day]' => date('d'),
'[extension]' => $file->guessClientExtension(),
'[month]' => date('m'),
'[name]' => pathinfo($file->getClientOriginalName(), \PATHINFO_FILENAME),
'[randomhash]' => bin2hex(random_bytes(20)),
'[slug]' => (new AsciiSlugger())
->slug(pathinfo($file->getClientOriginalName(), \PATHINFO_FILENAME))
->lower()
->toString(),
'[timestamp]' => time(),
'[uuid]' => Uuid::v4()->toRfc4122(),
'[ulid]' => new Ulid(),
'[year]' => date('Y'),
]);
};
});
$resolver->setNormalizer('allow_add', static function (Options $options, string $value): bool {
if ($value && !$options['multiple']) {
throw new InvalidArgumentException('Setting "allow_add" option to "true" when "multiple" option is "false" is not supported.');
}

return $value;
});
}

/**
* {@inheritdoc}
*/
public function mapDataToForms($currentFiles, $forms): void
{
/** @var FormInterface $fileForm */
$fileForm = current(iterator_to_array($forms));
$fileForm->setData($currentFiles);
}

/**
* {@inheritdoc}
*/
public function mapFormsToData($forms, &$currentFiles): void
{
/** @var FormInterface[] $children */
$children = iterator_to_array($forms);
$uploadedFiles = $children['path']->getData();

/** @var FileUploadState $state */
$state = $children['path']->getParent()->getConfig()->getAttribute('state');
$state->setCurrentFiles($currentFiles);
$state->setUploadedFiles($uploadedFiles);
$state->setDelete($children['delete']->getData());

if (!$state->isModified()) {
return;
}

if ($state->isAddAllowed() && !$state->isDelete()) {
$currentFiles = array_merge($currentFiles, $uploadedFiles);
} else {
$currentFiles = $uploadedFiles;
}
}

/**
* {@inheritdoc}
*/
public function transform($data)
{
return $data;
}

/**
* {@inheritdoc}
*/
public function reverseTransform($data)
{
return null === $data ? '' : $data;
}
}

+ 14
- 0
Repository/AbstractRepositoryQuery.php View File

{ {
return $this->andWhere('.status >= 0'); return $this->andWhere('.status >= 0');
} }

/*
* POSITION
*/

public function filterByPositionBiggerThan(int $position)
{
return $this->andWhere('.position > :position')->setParameter('position', $position);
}

public function filterByPositionSmallerThan(int $position)
{
return $this->andWhere('.position < :position')->setParameter('position', $position);
}
} }



+ 1
- 2
Repository/User/GroupUserRepositoryQuery.php View File



public function joinUsers(): self public function joinUsers(): self
{ {

if (!$this->isJoinUsers) { if (!$this->isJoinUsers) {
$this->isJoinUsers = true; $this->isJoinUsers = true;
return $this return $this
->innerJoin('.users', 'users');
->leftJoin('.users', 'users');
} }
return $this; return $this;
} }

+ 45
- 1
Resolver/UrlResolver.php View File





use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\RequestStack;


class UrlResolver class UrlResolver
{ {
protected ParameterBagInterface $parameterBag; protected ParameterBagInterface $parameterBag;
protected RequestStack $requestStack;


public function __construct(ParameterBagInterface $parameterBag)
public function __construct(ParameterBagInterface $parameterBag, RequestStack $requestStack)
{ {
$this->parameterBag = $parameterBag; $this->parameterBag = $parameterBag;
$this->requestStack = $requestStack;
} }


public function isServerLocalhost(): bool public function isServerLocalhost(): bool
} }
} }


public function isRouteAdmin(): bool
{
return $this->testRoute(['admin_', 'file_manager']);
}

public function isRouteLogin(): bool
{
return $this->testRoute(['sov_login', 'sov_logout', 'frontend_security_login']) ;
}

public function testRoute($mixed, $route = null): bool
{
if(is_null($route)) {
$route = $this->getRouteCurrentRequest();
}

if(!$route) {
return false;
}

if(is_array($mixed)) {
foreach($mixed as $testRoute) {
if($this->testRoute($testRoute, $route)) {
return true;
}
}

return false;
}

return strpos($route, $mixed) !== false;
}

public function getRouteCurrentRequest(): ?string
{
$requestAttributes = $this->requestStack->getCurrentRequest()->attributes->all();
$route = isset($requestAttributes['_route']) ? $requestAttributes['_route'] : null;

return $route;
}

} }

+ 3
- 2
Resources/assets/app/adminlte/main/init.js View File

window.addEventListener('load', (event) => { window.addEventListener('load', (event) => {


$(document).on('select2:open', () => {
// @TODO : cela met le focus sur le premier select2 du document
/*$(document).on('select2:open', () => {
document.querySelector('.select2-search__field').focus(); document.querySelector('.select2-search__field').focus();
});
});*/


SovNotification.init(); SovNotification.init();



+ 7
- 3
Resources/assets/functions/widgets.js View File

if ($select.data('width')) { if ($select.data('width')) {
options.width = 'auto' options.width = 'auto'
} }
if ($select.find('option[value=""]')) {

// @TODO : génère une erreur
/*if ($select.find('option[value=""]')) {
options.placeholder = $select.find('option[value=""]').html() options.placeholder = $select.find('option[value=""]').html()
}
}*/

options.placeholder = "";


var myselect = $select.select2(options); var myselect = $select.select2(options);


var event = new Event('change'); var event = new Event('change');
e.target.dispatchEvent(event); e.target.dispatchEvent(event);
}); });

myselect.on('select2:unselect', function (e) { myselect.on('select2:unselect', function (e) {
var event = new Event('change'); var event = new Event('change');
e.target.dispatchEvent(event); e.target.dispatchEvent(event);
}); });
SovTools.log(myselect);


myselect.off('select2:open') myselect.off('select2:open')



+ 1
- 0
Resources/config/services.yaml View File

parameters: parameters:
app.admin.logo: 'laclic.png' app.admin.logo: 'laclic.png'
app.admin.logo_sidebar: 'laclic.png'
app.site_name: 'laclic-sov' app.site_name: 'laclic-sov'
app.mail_debug: '' app.mail_debug: ''



+ 1
- 0
Resources/translations/admin.fr.yaml View File

panels: panels:
general: Général general: Général
configuration: Configuration configuration: Configuration
conf: Configuration
gallery: Galerie gallery: Galerie
seo: Référencement seo: Référencement
opengraph: Opengraph opengraph: Opengraph

+ 0
- 1
Resources/views/adminlte/crud/form_theme.html.twig View File

{{ form_widget(form) }} {{ form_widget(form) }}
{% endblock file_manager_position_row %} {% endblock file_manager_position_row %}



{% block file_manager_widget %} {% block file_manager_widget %}
{% if form.vars.ea_crud_form.ea_field is not null %} {% if form.vars.ea_crud_form.ea_field is not null %}
{% set managerDir = form.vars.ea_crud_form.ea_field.customOptions.get('managerDir') %} {% set managerDir = form.vars.ea_crud_form.ea_field.customOptions.get('managerDir') %}

+ 16
- 1
Twig/TwigExtension.php View File

new TwigFunction('ea_url_short', [$this, 'generateEaUrl']), new TwigFunction('ea_url_short', [$this, 'generateEaUrl']),
new TwigFunction('is_instance_of', [$this, 'isInstanceOf']), new TwigFunction('is_instance_of', [$this, 'isInstanceOf']),
new TwigFunction('logo_admin', [$this, 'getLogoAdmin']), new TwigFunction('logo_admin', [$this, 'getLogoAdmin']),
new TwigFunction('asset_url', [$this, 'getAssetUrl']),
]; ];
} }


]; ];
} }


public function getAssetUrl($path)
{
$context = $this->router->getContext();
$host = $context->getScheme().'://'.$context->getHost().'/';

return $host.$path;
}


public function rot13(string $string): string public function rot13(string $string): string
{ {
return str_rot13($string); return str_rot13($string);


public function getLogoAdmin(): string public function getLogoAdmin(): string
{ {
return '<img class="logo-admin" src="assets/img/' . $this->getParameter('app.admin.logo') . '" >';
$image = $this->getParameter('app.admin.logo_sidebar');
if(!$image) {
$image = $this->getParameter('app.admin.logo');
}

return '<img class="logo-admin" src="assets/img/' . $image . '" >';
} }
} }

Loading…
Cancel
Save