Commit ff11addd by Julien Jorry

BO : add translation on admin + add admin css + fix bugs on…

BO : add translation on admin + add admin css + fix bugs on user/adherent/prestataire + update schema for flux
parent 74ee6743
.traductions .container {
width: 100%;
max-width: 100%;
}
\ No newline at end of file
/*
* Welcome to your app's main JavaScript file!
*
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
// any CSS you require will output into a single css file (app.css in this case)
require('../css/admin.css');
// Need jQuery? Install it with "yarn add jquery", then uncomment to require it.
// var $ = require('jquery');
...@@ -10,5 +10,3 @@ require('../css/app.css'); ...@@ -10,5 +10,3 @@ require('../css/app.css');
// Need jQuery? Install it with "yarn add jquery", then uncomment to require it. // Need jQuery? Install it with "yarn add jquery", then uncomment to require it.
// var $ = require('jquery'); // var $ = require('jquery');
console.log('Hello Webpack Encore! Edit me in assets/js/app.js');
...@@ -40,4 +40,7 @@ return [ ...@@ -40,4 +40,7 @@ return [
FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true], FOS\CKEditorBundle\FOSCKEditorBundle::class => ['all' => true],
App\Application\Sonata\MediaBundle\ApplicationSonataMediaBundle::class => ['all' => true], App\Application\Sonata\MediaBundle\ApplicationSonataMediaBundle::class => ['all' => true],
Bazinga\GeocoderBundle\BazingaGeocoderBundle::class => ['all' => true], Bazinga\GeocoderBundle\BazingaGeocoderBundle::class => ['all' => true],
Sonata\TranslationBundle\SonataTranslationBundle::class => ['all' => true],
Sonata\IntlBundle\SonataIntlBundle::class => ['all' => true],
Lexik\Bundle\TranslationBundle\LexikTranslationBundle::class => ['all' => true]
]; ];
lexik_translation:
fallback_locale: [fr]
managed_locales: [fr,en]
storage:
type: orm
base_layout: "/bundles/LexikTranslationBundle/layout.html.twig"
exporter:
use_yml_tree: true
\ No newline at end of file
...@@ -103,6 +103,6 @@ security: ...@@ -103,6 +103,6 @@ security:
# Secured part of the site # Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part. # This config requires being logged for the whole site and having the admin role for the admin part.
# Change these rules to adapt them to your needs # Change these rules to adapt them to your needs
- { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SUPER_ADMIN, ROLE_SONATA_ADMIN] } - { path: ^/admin/, role: [ROLE_ADMIN, ROLE_SUPER_ADMIN, ROLE_SONATA_ADMIN, ROLE_ADMIN_SIEGE, ROLE_REDACTEUR, ROLE_TRESORIER, ROLE_GESTION_GROUPE, ROLE_COMPTOIR, ROLE_CONTACT] }
- { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
...@@ -17,10 +17,11 @@ sonata_user: ...@@ -17,10 +17,11 @@ sonata_user:
sonata_block: sonata_block:
default_contexts: [sonata_page_bundle] default_contexts: [sonata_page_bundle]
blocks: blocks:
sonata.block.service.text:
contexts: [admin]
sonata.admin.block.stats:
contexts: [admin]
sonata.admin.block.admin_list: sonata.admin.block.admin_list:
contexts: [admin] contexts: [admin]
sonata.admin.block.search_result:
#sonata.admin_doctrine_orm.block.audit: contexts: [admin]
# contexts: [admin] \ No newline at end of file
sonata.block.service.text:
\ No newline at end of file
...@@ -42,6 +42,8 @@ sonata_admin: ...@@ -42,6 +42,8 @@ sonata_admin:
# button_history: '@SonataAdmin/Button/history_button.html.twig' # button_history: '@SonataAdmin/Button/history_button.html.twig'
# button_list: '@SonataAdmin/Button/list_button.html.twig' # button_list: '@SonataAdmin/Button/list_button.html.twig'
# button_show: '@SonataAdmin/Button/show_button.html.twig' # button_show: '@SonataAdmin/Button/show_button.html.twig'
assets:
extra_stylesheets: ['build/admin.css']
dashboard: dashboard:
# DASHBOARD de l'admin # DASHBOARD de l'admin
# #
...@@ -65,11 +67,12 @@ sonata_admin: ...@@ -65,11 +67,12 @@ sonata_admin:
# type: sonata.admin.block.stats # type: sonata.admin.block.stats
# settings: # settings:
# code: admin.adherent.gerer # code: admin.adherent.gerer
# icon: fas fa-user-tie # icon: fas fa-user
# text: Adherents # text: Adherents
# color: bg-info # color: bg-info
# filters: # filters:
# enabled: { value: 1 } # enabled: { value: 1 }
# _per_page: { value: 32 }
# - # -
# class: col-xs-4 col-md-3 # class: col-xs-4 col-md-3
# position: top # position: top
...@@ -159,6 +162,7 @@ sonata_admin: ...@@ -159,6 +162,7 @@ sonata_admin:
roles: [ ROLE_SUPER_ADMIN, ROLE_ADMIN_SIEGE, ROLE_TRESORIER, ROLE_GESTION_GROUPE, ROLE_COMPTOIR, ROLE_CONTACT ] roles: [ ROLE_SUPER_ADMIN, ROLE_ADMIN_SIEGE, ROLE_TRESORIER, ROLE_GESTION_GROUPE, ROLE_COMPTOIR, ROLE_CONTACT ]
items: items:
- admin.prestataire.gerer - admin.prestataire.gerer
# - admin.prestataired.gerer
- admin.prestataire.cotisations - admin.prestataire.cotisations
- admin.groupepresta.gerer - admin.groupepresta.gerer
sonata.admin.group.groupe: sonata.admin.group.groupe:
...@@ -213,6 +217,15 @@ sonata_admin: ...@@ -213,6 +217,15 @@ sonata_admin:
roles: [ ROLE_SUPER_ADMIN, ROLE_ADMIN_SIEGE, ROLE_TRESORIER, ROLE_GESTION_GROUPE, ROLE_COMPTOIR, ROLE_CONTACT, ROLE_REDACTEUR ] roles: [ ROLE_SUPER_ADMIN, ROLE_ADMIN_SIEGE, ROLE_TRESORIER, ROLE_GESTION_GROUPE, ROLE_COMPTOIR, ROLE_CONTACT, ROLE_REDACTEUR ]
items: items:
- admin.faq.gerer - admin.faq.gerer
sonata.admin.group.traduction:
keep_open: false
on_top: true
label: "Traductions"
label_catalogue: SonataAdminBundle
icon: '<i class="fa fa-flag"></i>'
roles: [ ROLE_SUPER_ADMIN, ROLE_ADMIN_SIEGE, ROLE_REDACTEUR ]
items:
- admin.traduction.gerer
# Gérer l'affichage du menu de l'admin en fonction des roles # Gérer l'affichage du menu de l'admin en fonction des roles
# groups: # groups:
...@@ -222,11 +235,4 @@ sonata_admin: ...@@ -222,11 +235,4 @@ sonata_admin:
# items: # items:
# - app.admin.post # - app.admin.post
# roles: [ ROLE_ONE, ROLE_TWO ] # roles: [ ROLE_ONE, ROLE_TWO ]
sonata_block:
blocks:
sonata.admin.block.stats:
contexts: [admin]
sonata.admin.block.admin_list:
contexts: [admin]
sonata.admin.block.search_result:
contexts: [admin]
sonata_admin:
assets:
extra_stylesheets:
- bundles/sonatatranslation/css/sonata-translation.css
sonata_block:
blocks:
sonata_translation.block.locale_switcher: ~
sonata_translation:
locale_switcher: true
locales: ['en', 'fr']
default_locale: 'fr'
gedmo:
enabled: true
knplabs:
enabled: true
...@@ -14,3 +14,10 @@ sonata_user_admin_resetting: ...@@ -14,3 +14,10 @@ sonata_user_admin_resetting:
fos_user: fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml" resource: "@FOSUserBundle/Resources/config/routing/all.xml"
sonata_translation:
resource: '@SonataTranslationBundle/Resources/config/routes.yaml'
lexik_translation_edition:
resource: "@LexikTranslationBundle/Resources/config/routing.yml"
prefix: /admin
\ No newline at end of file
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters: parameters:
locale: 'en' locale: 'en'
sonata.user.admin.user.controller: 'App\Controller\CRUD\CRUDController'
services: services:
# default configuration for services in *this* file # default configuration for services in *this* file
...@@ -57,7 +58,7 @@ services: ...@@ -57,7 +58,7 @@ services:
admin.adherent.gerer: admin.adherent.gerer:
class: App\Admin\AdherentAdmin class: App\Admin\AdherentAdmin
# arguments: [~, App\Entity\OBJECT, 'PixSortableBehaviorBundle:SortableAdmin'] # arguments: [~, App\Entity\OBJECT, 'PixSortableBehaviorBundle:SortableAdmin']
arguments: [~, App\Entity\User, ~] arguments: [~, App\Entity\User, 'App\Controller\CRUD\CRUDController']
tags: tags:
- name: sonata.admin - name: sonata.admin
manager_type: orm manager_type: orm
...@@ -82,7 +83,7 @@ services: ...@@ -82,7 +83,7 @@ services:
admin.prestataire.gerer: admin.prestataire.gerer:
class: App\Admin\PrestataireAdmin class: App\Admin\PrestataireAdmin
arguments: [~, App\Entity\User, ~] arguments: [~, App\Entity\User, 'App\Controller\CRUD\CRUDController']
tags: tags:
- name: sonata.admin - name: sonata.admin
manager_type: orm manager_type: orm
...@@ -92,6 +93,19 @@ services: ...@@ -92,6 +93,19 @@ services:
calls: calls:
- [ setUserManager, ['@fos_user.user_manager']] - [ setUserManager, ['@fos_user.user_manager']]
admin.prestataired.gerer:
class: App\Admin\PrestataireDAdmin
arguments: [~, App\Entity\Prestataire, ~]
tags:
- name: sonata.admin
manager_type: orm
group: "Prestataire"
label: "Gérer 2"
public: true
calls:
- [ setUserManager, ['@fos_user.user_manager']]
- [ addChild, ['@sonata.user.admin.user', 'user']]
admin.prestataire.cotisations: admin.prestataire.cotisations:
class: App\Admin\CotisationPrestataireAdmin class: App\Admin\CotisationPrestataireAdmin
arguments: [~, App\Entity\Cotisation, ~] arguments: [~, App\Entity\Cotisation, ~]
...@@ -160,6 +174,16 @@ services: ...@@ -160,6 +174,16 @@ services:
label: "FAQs" label: "FAQs"
public: true public: true
admin.traduction.gerer:
class: App\Admin\TraductionAdmin
arguments: [~, Lexik\Bundle\TranslationBundle\Entity\Translation, ~]
tags:
- name: sonata.admin
manager_type: orm
group: "Traduction"
label: "Traductions"
public: true
# admin.flux.gerer: # admin.flux.gerer:
# class: App\Admin\FluxAdmin # class: App\Admin\FluxAdmin
# arguments: [~, App\Entity\Transaction, ~] # arguments: [~, App\Entity\Transaction, ~]
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -22,6 +22,15 @@ class AdherentAdmin extends UserAdmin ...@@ -22,6 +22,15 @@ class AdherentAdmin extends UserAdmin
protected $baseRouteName = 'adherent'; protected $baseRouteName = 'adherent';
protected $baseRoutePattern = 'adherent'; protected $baseRoutePattern = 'adherent';
protected $datagridValues = [
// reverse order (default = 'ASC')
'_sort_order' => 'DESC',
// name of the ordered field (default = the model's id field, if any)
'_sort_by' => 'ecompte',
// '_page' => 1,
// '_per_page' => 32
];
public function configure() public function configure()
{ {
parent::configure(); parent::configure();
...@@ -49,10 +58,6 @@ class AdherentAdmin extends UserAdmin ...@@ -49,10 +58,6 @@ class AdherentAdmin extends UserAdmin
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{ {
parent::configureDatagridFilters($datagridMapper); parent::configureDatagridFilters($datagridMapper);
$datagridMapper
->add('username')
->add('email')
;
} }
...@@ -63,8 +68,9 @@ class AdherentAdmin extends UserAdmin ...@@ -63,8 +68,9 @@ class AdherentAdmin extends UserAdmin
->addIdentifier('username') ->addIdentifier('username')
->addIdentifier('email') ->addIdentifier('email')
->addIdentifier('adherent.ecompte', null, array('label' => 'Ecompte')) ->addIdentifier('adherent.ecompte', null, array('label' => 'Ecompte'))
->add('groups')
->addIdentifier('enabled', null, array('label' => 'Activé', 'datatype' => 'App.User', 'template' => '@SonataAdmin/Boolean/editable_boolean.html.twig')) ->addIdentifier('enabled', null, array('label' => 'Activé', 'datatype' => 'App.User', 'template' => '@SonataAdmin/Boolean/editable_boolean.html.twig'))
->addIdentifier('createdAt') // ->addIdentifier('createdAt')
; ;
if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH')) { if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH')) {
...@@ -76,7 +82,7 @@ class AdherentAdmin extends UserAdmin ...@@ -76,7 +82,7 @@ class AdherentAdmin extends UserAdmin
protected function configureRoutes(RouteCollection $collection) protected function configureRoutes(RouteCollection $collection)
{ {
$collection->remove('delete'); // $collection->remove('delete');
} }
/** /**
...@@ -85,7 +91,14 @@ class AdherentAdmin extends UserAdmin ...@@ -85,7 +91,14 @@ class AdherentAdmin extends UserAdmin
public function createQuery($context = 'list') public function createQuery($context = 'list')
{ {
$query = parent::createQuery($context); $query = parent::createQuery($context);
$query->andWhere($query->getRootAliases()[0] . '.adherent IS NOT NULL'); $role = 'ROLE_ADHERENT';
// $query->andWhere($query->getRootAliases()[0] . '.adherent IS NOT NULL');
$query->leftJoin($query->getRootAliases()[0] . '.groups', 'g')
->where($query->expr()->orX(
$query->expr()->like($query->getRootAliases()[0] . '.roles', ':roles'),
$query->expr()->like('g.roles', ':roles')
))
->setParameter('roles', '%"'.$role.'"%');
return $query; return $query;
} }
} }
...@@ -22,11 +22,6 @@ class PrestataireAdmin extends UserAdmin ...@@ -22,11 +22,6 @@ class PrestataireAdmin extends UserAdmin
{ {
protected $baseRouteName = 'prestataire'; protected $baseRouteName = 'prestataire';
protected $baseRoutePattern = 'prestataire'; protected $baseRoutePattern = 'prestataire';
protected $datagridValues = [
'_page' => 1,
'_per_page' => 32,
];
public function configure() public function configure()
{ {
......
<?php
namespace App\Admin;
use App\Admin\UserAdmin;
use App\Entity\Geoloc;
use App\Entity\Prestataire;
use App\Entity\User;
use App\Entity\Usergroup;
use Doctrine\ORM\Query;
use FOS\UserBundle\Model\UserManagerInterface;
use Knp\Menu\ItemInterface as MenuItemInterface;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Route\RouteCollection;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\MediaBundle\Form\Type\MediaType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class PrestataireDAdmin extends AbstractAdmin
{
protected $baseRouteName = 'prestataired';
protected $baseRoutePattern = 'prestataired';
public function configure()
{
parent::configure();
}
protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
{
if (!$childAdmin && !in_array($action, ['edit', 'show'])) {
return;
}
$admin = $this->isChild() ? $this->getParent() : $this;
$id = $admin->getRequest()->get('id');
$user = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(User::class)->findOneBy(array('prestataire' => $id));
if ($this->isGranted('EDIT') && $user != null) {
$menu->addChild('Edit User', [
'uri' => $this->getConfigurationPool()->getContainer()->get('router')->generate('admin_app_user_edit', ['id' => $user->getId()], UrlGeneratorInterface::ABSOLUTE_URL)
]);
}
}
/**
* {@inheritdoc}
*/
protected function configureFormFields(FormMapper $formMapper): void
{
// Initialize prestataire
$presta = $this->getSubject();
$user = $this->userManager->createUser();
$user->setEnabled(1); // enable the user or enable it later with a confirmation token in the email
// $this->userManager->updateUser($user);
$groupe = $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository(Usergroup::class)->findOneByName('Prestataire');
$user->setEnabled(true);
$user->addGroup($groupe);
$user->addRole('ROLE_PRESTATAIRE');
// $presta = new Prestataire();
$presta->setGeoloc(new Geoloc());
$user->setPrestataire($presta);
// get the current Image instance
$imageHelp = null;
if (!empty($user->getPrestataire()) && !empty($user->getPrestataire()->getMedia())) {
$image = $user->getPrestataire()->getMedia();
if ($image && ($webPath = $image->getWebPath())) {
// get the container so the full path to the image can be set
$container = $this->getConfigurationPool()->getContainer();
$fullPath = $container->get('request_stack')->getCurrentRequest()->getBasePath().'/'.$webPath;
// add a 'help' option containing the preview's img tag
$imageHelp = '<img src="'.$fullPath.'" class="admin-preview" />';
}
}
$formMapper
->tab('Prestataire')
->with('General', ['class' => 'col-md-7'])
->add('raison', TextType::class, array(
'label' => 'Raison :',
'required' => true
))
->add('statut', TextType::class, array(
'label' => 'Statut :',
'required' => false
))
->add('siret', TextType::class, array(
'label' => 'SIRET :',
'required' => true
))
->add('iban', TextType::class, array(
'label' => 'IBAN :',
'required' => true
))
->end()
->with('Responsable', ['class' => 'col-md-5'])
->add('metier', TextType::class, array(
'label' => 'Métier :',
'required' => true
))
->add('responsable', TextType::class, array(
'label' => 'Responsable :',
'required' => false
))
->end()
->with('Addresse', ['class' => 'col-md-7'])
->add('geoloc.adresse', TextType::class, array(
'label' => 'Addresse :',
'required' => false
))
->add('geoloc.cpostal', TextType::class, array(
'label' => 'Code postal :',
'required' => false
))
->add('geoloc.ville', TextType::class, array(
'label' => 'Ville :',
'required' => false
))
->add('geoloc.lat', TextType::class, array(
'label' => 'Latitude :',
'required' => false
))
->add('geoloc.lon', TextType::class, array(
'label' => 'Longitude :',
'required' => false
))
->end()
->with('Image', ['class' => 'col-md-5'])
->add('media', MediaType::class, array(
'provider' => 'sonata.media.provider.image',
'context' => 'prestataire',
'help' => $imageHelp
))
->end()
->end()
;
parent::configureFormFields($formMapper);
}
/**
* {@inheritdoc}
*/
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{
parent::configureDatagridFilters($datagridMapper);
$datagridMapper
->add('raison')
->add('statut')
;
}
/**
* @param UserManagerInterface $userManager
*/
public function setUserManager(UserManagerInterface $userManager): void
{
$this->userManager = $userManager;
}
/**
* @return UserManagerInterface
*/
public function getUserManager()
{
return $this->userManager;
}
protected function configureListFields(ListMapper $listMapper): void
{
unset($this->listModes['mosaic']);
$listMapper
->addIdentifier('user.username')
->addIdentifier('user.email')
->addIdentifier('raison')
->addIdentifier('user.enabled', null, array('label' => 'Activé', 'datatype' => 'App.User', 'template' => '@SonataAdmin/Boolean/editable_boolean.html.twig'))
->addIdentifier('user.createdAt')
;
// if ($this->isGranted('ROLE_ALLOWED_TO_SWITCH')) {
// $listMapper
// ->addIdentifier('user.impersonating', 'string', ['template' => '@SonataUser/Admin/Field/impersonating.html.twig'])
// ;
// }
}
protected function configureRoutes(RouteCollection $collection)
{
$collection->remove('delete');
}
/**
* {@inheritdoc}
*/
public function createQuery($context = 'list')
{
$query = parent::createQuery($context);
// $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
$query->innerJoin('o.user', 'u')
->addSelect('u');
return $query;
}
}
<?php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Route\RouteCollection;
/**
* TRADUCTION ADMIN
*/
class TraductionAdmin extends AbstractAdmin
{
protected $baseRouteName = 'lexik_translation_overview';
protected $baseRoutePattern = 'translations';
/**
* {@inheritdoc}
*/
public function configureRoutes(RouteCollection $collection)
{
$collection->add('list', 'list', [
'_controller' => 'LexikTranslationBundle:Translation:overview',
]);
$collection->add('grid', 'grid', [
'_controller' => 'LexikTranslationBundle:Translation:grid',
]);
$collection->add('new', 'new', [
'_controller' => 'LexikTranslationBundle:Translation:new',
]);
}
}
...@@ -23,6 +23,8 @@ class UserAdmin extends SonataUserAdmin ...@@ -23,6 +23,8 @@ class UserAdmin extends SonataUserAdmin
'_sort_order' => 'DESC', '_sort_order' => 'DESC',
// name of the ordered field (default = the model's id field, if any) // name of the ordered field (default = the model's id field, if any)
'_sort_by' => 'updatedAt', '_sort_by' => 'updatedAt',
// '_page' => 1,
// '_per_page' => 32
]; ];
public function configure() public function configure()
...@@ -55,7 +57,13 @@ class UserAdmin extends SonataUserAdmin ...@@ -55,7 +57,13 @@ class UserAdmin extends SonataUserAdmin
protected function configureRoutes(RouteCollection $collection) protected function configureRoutes(RouteCollection $collection)
{ {
if ($this->isChild()) {
$collection->remove('delete'); $collection->remove('delete');
return;
}
// This is the route configuration as a parent
$collection->clear();
} }
/** /**
...@@ -63,11 +71,9 @@ class UserAdmin extends SonataUserAdmin ...@@ -63,11 +71,9 @@ class UserAdmin extends SonataUserAdmin
*/ */
protected function configureDatagridFilters(DatagridMapper $datagridMapper): void protected function configureDatagridFilters(DatagridMapper $datagridMapper): void
{ {
parent::configureDatagridFilters($datagridMapper);
$datagridMapper $datagridMapper
->add('enabled') ->add('enabled')
// ->add('email', null, [
// 'show_filter' => true
// ])
; ;
} }
......
...@@ -120,7 +120,7 @@ class UserAdmin extends BaseUserAdmin ...@@ -120,7 +120,7 @@ class UserAdmin extends BaseUserAdmin
->with('Groups', ['class' => 'col-md-8'])->end() ->with('Groups', ['class' => 'col-md-8'])->end()
->with('Status', ['class' => 'col-md-4'])->end() ->with('Status', ['class' => 'col-md-4'])->end()
// ->with('Keys', ['class' => 'col-md-4'])->end() // ->with('Keys', ['class' => 'col-md-4'])->end()
// ->with('Roles', ['class' => 'col-md-12'])->end() ->with('Roles', ['class' => 'col-md-12'])->end()
->end() ->end()
; ;
...@@ -183,14 +183,14 @@ class UserAdmin extends BaseUserAdmin ...@@ -183,14 +183,14 @@ class UserAdmin extends BaseUserAdmin
'multiple' => true, 'multiple' => true,
]) ])
->end() ->end()
// ->with('Roles') ->with('Roles')
// ->add('realRoles', SecurityRolesType::class, [ ->add('realRoles', SecurityRolesType::class, [
// 'label' => 'form.label_roles', 'label' => 'form.label_roles',
// 'expanded' => true, 'expanded' => true,
// 'multiple' => true, 'multiple' => true,
// 'required' => false, 'required' => false,
// ]) ])
// ->end() ->end()
// ->with('Keys') // ->with('Keys')
// ->add('token', null, ['required' => false]) // ->add('token', null, ['required' => false])
// ->add('twoStepVerificationCode', null, ['required' => false]) // ->add('twoStepVerificationCode', null, ['required' => false])
......
<?php
namespace App\Controller\CRUD;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
class CRUDController extends Controller
{
public function deleteAction($id)
{
$request = $this->getRequest();
$id = $request->get($this->admin->getIdParameter());
$object = $this->admin->getObject($id);
if (!$object) {
throw $this->createNotFoundException(sprintf('unable to find the object with id: %s', $id));
}
$currentUserId = $this->getUser()->getId(); // ID of the current user
if ($currentUserId == $id) {
$this->addFlash(
'sonata_flash_error',
'Vous ne pouvez pas supprimer votre compte !'
);
return $this->redirectTo($object);
}
if ($object->hasRoale('ROLE_SUPER_ADMIN') || $object->hasRole('ROLE_ADMIN_SIEGE')) {
$this->addFlash(
'sonata_flash_error',
'Vous ne pouvez pas supprimer le compte admin !'
);
return $this->redirectTo($object);
}
return parent::deleteAction($id);
}
public function batchActionDelete(ProxyQueryInterface $query)
{
$request = $this->getRequest();
$currentUserId = $this->getUser()->getId(); // ID of the current user
$selectedUsers = $query->execute();
foreach ($selectedUsers as $selectedUser) {
if ($selectedUser->getId() == $currentUserId) {
$this->addFlash(
'sonata_flash_error',
'Vous ne pouvez pas supprimer votre compte !'
);
return new RedirectResponse(
$this->admin->generateUrl('list', array('filter' => $this->admin->getFilterParameters()))
);
}
if ($selectedUser->hasRole('ROLE_SUPER_ADMIN') || $selectedUser->hasRole('ROLE_ADMIN_SIEGE')) {
$this->addFlash(
'sonata_flash_error',
'Vous ne pouvez pas supprimer le compte admin !'
);
return new RedirectResponse(
$this->admin->generateUrl('list', array('filter' => $this->admin->getFilterParameters()))
);
}
}
return parent::batchActionDelete($query);
}
}
<?php
namespace App\Entity\EntityTrait;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Validator\Constraints as Assert;
trait FileEntityTrait
{
/**
* @var null|File|UploadedFile
*/
protected $file;
/**
* @var null|string
*/
protected $oldPath = null;
/**
* @var null|int
*
* @ORM\Column(type="integer", length=255, nullable=true)
*/
protected $size;
/**
* @var null|string
*
* @ORM\Column(type="string", length=10, nullable=true)
*/
protected $extension;
/**
* @var null|string
*
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $type;
/**
* @var null|string
*
* @ORM\Column(name="file", type="string", length=255, nullable=true)
*/
protected $path = null;
/**
* @param File|null $file
* @return $this
*/
public function setFile(File $file = null)
{
$this->file = $file;
return $this;
}
/**
* @return null|File|UploadedFile
*/
public function getFile(): ?File
{
return $this->file;
}
/**
* @return null|string
*/
public function getOldPath(): ?string
{
return $this->oldPath;
}
/**
* @param null|string $oldPath
* @return $this
*/
public function setOldPath(?string $oldPath)
{
$this->oldPath = $oldPath;
return $this;
}
/**
* @return int|null
*/
public function getSize(): ?int
{
return $this->size;
}
/**
* @param int|null $size
* @return $this
*/
public function setSize(?int $size)
{
$this->size = $size;
return $this;
}
/**
* @return null|string
*/
public function getExtension(): ?string
{
return $this->extension;
}
/**
* @param null|string $extension
* @return $this
*/
public function setExtension(?string $extension)
{
$this->extension = $extension;
return $this;
}
/**
* @return null|string
*/
public function getType(): ?string
{
return $this->type;
}
/**
* @param null|string $type
* @return $this
*/
public function setType(?string $type)
{
$this->type = $type;
return $this;
}
/**
* @return null|string
*/
public function getPath(): ?string
{
return $this->path;
}
/**
* @param null|string $path
* @return $this
*/
public function setPath(?string $path)
{
$this->path = $path;
return $this;
}
public function getAbsolutePath()
{
return null === $this->getPath()
? null
: $this->getUploadRootDir().'/'.$this->getPath();
}
public function getWebPath()
{
return null === $this->getPath()
? null
: $this->getUploadDir().'/'.$this->getPath();
}
public function getUploadRootDir()
{
return __DIR__.'/../../../../web/'.$this->getUploadDir();
}
public function getUploadDir()
{
return 'uploads/'.strtolower($this->getType());
}
/**
* Au chargement de l'entité génération d'un objet File stocker dans la proprieté file
* @ORM\PostLoad()
*/
public function postLoadFile()
{
if($this->getPath() != null) {
try {
$this->setFile(new File($this->getAbsolutePath()));
} catch (\Exception $e){
}
}
}
/**
* A la modification ou création de l'entité je vérifie qu'il y a un UploadedFile dans la proprieté file
* @ORM\PreFlush()
*/
public function upload()
{
if (null === $this->getFile() || !$this->getFile() instanceof UploadedFile) {
return;
}
$file_name = date('m-d-Y_his') . '-' . $this->getFile()->getClientOriginalName();
if($this->getPath() != null) {
$this->setOldPath($this->getPath());
}
$this->setPath($file_name);
$this->setSize($this->getFile()->getSize());
$this->setExtension($this->getFile()->getClientOriginalExtension());
$fs = new Filesystem();
if (!$fs->exists($this->getUploadRootDir())) {
$fs->mkdir($this->getUploadRootDir(), 0775);
}
$this->file->move(
$this->getUploadRootDir(), $this->getPath()
);
}
/**
* Après la création ou la modification de l'entité, si le fichier à été remplacé je supprime l'ancien
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function cleanOldFile()
{
if($this->getOldPath() !== null) {
$fs = new Filesystem();
try {
$fs->remove($this->getUploadRootDir().'/'. $this->getOldPath());
} catch(\Exception $exception) {
}
}
}
}
\ No newline at end of file
<?php
namespace App\Entity\EntityTrait;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Validator\Constraints as Assert;
trait OldFileEntityTrait
{
/**
* @var null|File|UploadedFile
*/
protected $file;
/**
* @var null|string
*/
protected $oldPath = null;
/**
* @var null|int
*
* @ORM\Column(type="integer", length=255, nullable=true)
*/
protected $size;
/**
* @var null|string
*
* @ORM\Column(type="string", length=10, nullable=true)
*/
protected $extension;
/**
* @var null|string
*
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $type;
/**
* @var null|string
*
* @ORM\Column(name="file", type="string", length=255, nullable=true)
*/
protected $path = null;
/**
* @param File|null $file
* @return $this
*/
public function setFile(File $file = null)
{
$this->file = $file;
return $this;
}
/**
* @return null|File|UploadedFile
*/
public function getFile(): ?File
{
return $this->file;
}
/**
* @return null|string
*/
public function getOldPath(): ?string
{
return $this->oldPath;
}
/**
* @param null|string $oldPath
* @return $this
*/
public function setOldPath(?string $oldPath)
{
$this->oldPath = $oldPath;
return $this;
}
/**
* @return int|null
*/
public function getSize(): ?int
{
return $this->size;
}
/**
* @param int|null $size
* @return $this
*/
public function setSize(?int $size)
{
$this->size = $size;
return $this;
}
/**
* @return null|string
*/
public function getExtension(): ?string
{
return $this->extension;
}
/**
* @param null|string $extension
* @return $this
*/
public function setExtension(?string $extension)
{
$this->extension = $extension;
return $this;
}
/**
* @return null|string
*/
public function getType(): ?string
{
return $this->type;
}
/**
* @param null|string $type
* @return $this
*/
public function setType(?string $type)
{
$this->type = $type;
return $this;
}
/**
* @return null|string
*/
public function getPath(): ?string
{
return $this->path;
}
/**
* @param null|string $path
* @return $this
*/
public function setPath(?string $path)
{
$this->path = $path;
return $this;
}
public function getAbsolutePath()
{
return null === $this->getPath()
? null
: $this->getUploadRootDir().'/'.$this->getPath();
}
public function getWebPath()
{
return null === $this->getPath()
? null
: $this->getUploadDir().'/'.$this->getPath();
}
public function getUploadRootDir()
{
return __DIR__.'/../../../../web/'.$this->getUploadDir();
}
public function getUploadDir()
{
return 'uploads/'.strtolower($this->getType());
}
/**
* Au chargement de l'entité génération d'un objet File stocker dans la proprieté file
* @ORM\PostLoad()
*/
public function postLoadFile()
{
if($this->getPath() != null) {
try {
$this->setFile(new File($this->getAbsolutePath()));
} catch (\Exception $e){
}
}
}
/**
* A la modification ou création de l'entité je vérifie qu'il y a un UploadedFile dans la proprieté file
* @ORM\PreFlush()
*/
public function upload()
{
if (null === $this->getFile() || !$this->getFile() instanceof UploadedFile) {
return;
}
$file_name = date('m-d-Y_his') . '-' . $this->getFile()->getClientOriginalName();
if($this->getPath() != null) {
$this->setOldPath($this->getPath());
}
$this->setPath($file_name);
$this->setSize($this->getFile()->getSize());
$this->setExtension($this->getFile()->getClientOriginalExtension());
$fs = new Filesystem();
if (!$fs->exists($this->getUploadRootDir())) {
$fs->mkdir($this->getUploadRootDir(), 0775);
}
$this->file->move(
$this->getUploadRootDir(), $this->getPath()
);
}
/**
* Après la création ou la modification de l'entité, si le fichier à été remplacé je supprime l'ancien
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function cleanOldFile()
{
if($this->getOldPath() !== null) {
$fs = new Filesystem();
try {
$fs->remove($this->getUploadRootDir().'/'. $this->getOldPath());
} catch(\Exception $exception) {
}
}
}
}
\ No newline at end of file
<?php
namespace App\Entity\EntityTrait;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
trait SoftDeletableEntityTrait
{
/**
* @var \DateTime|null
*
* @ORM\Column(type="datetime", nullable=true)
* @Assert\DateTime()
*/
private $deletedAt;
/**
* @param \DateTime|null $deletedAt
*
* @return $this
*/
public function setDeletedAt(?\DateTime $deletedAt = null)
{
$this->deletedAt = $deletedAt;
return $this;
}
public function getDeletedAt(): ?\DateTime
{
return $this->deletedAt;
}
public function isDeleted(): bool
{
return null !== $this->deletedAt;
}
}
<?php
namespace App\Entity;
use App\Entity\EntityTrait\EnablableEntityTrait;
use App\Entity\Transaction;
use App\Entity\Transfert;
use App\Entity\User;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* FLUX = TRANSFERT ou TRANSACTION
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"transfert" = "Transfert", "transaction" = "Transaction"})
*/
abstract class Flux
{
use TimestampableEntity;
/**
* @var int
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="user", cascade={"all"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
*/
protected $operateur;
/**
* TYPE DE TRANSACTION :
* @var string
*
* @ORM\Column(name="type", type="string", length=3)
*/
protected $type;
/**
* @var float
*
* @ORM\Column(name="montant", type="decimal", precision=7, scale=2)
*/
protected $montant;
/**
* @var null|string
*
* @ORM\Column(name="reference", type="string", length=255, nullable=true)
*/
protected $reference;
protected $expediteur=null;
protected $destinataire=null;
}
...@@ -94,6 +94,14 @@ class Prestataire ...@@ -94,6 +94,14 @@ class Prestataire
private $accept = false; private $accept = false;
/** /**
* @var bool
*
* @ORM\Column(name="partenaire", type="boolean", nullable=false)
*/
private $partenaire = false;
/**
* @var null|string (champ libre) * @var null|string (champ libre)
* *
* @ORM\Column(name="horaires", type="string", length=255, nullable=true) * @ORM\Column(name="horaires", type="string", length=255, nullable=true)
...@@ -125,7 +133,7 @@ class Prestataire ...@@ -125,7 +133,7 @@ class Prestataire
/** /**
* @var User * @var User
* *
* @ORM\OneToOne(targetEntity="User", cascade={"all"}, mappedBy="prestataire") * @ORM\OneToOne(targetEntity="User", cascade={"all"}, mappedBy="prestataire", fetch="LAZY")
*/ */
protected $user; protected $user;
...@@ -323,7 +331,7 @@ class Prestataire ...@@ -323,7 +331,7 @@ class Prestataire
/** /**
* @return User * @return User
*/ */
public function getUser(): User public function getUser(): ?User
{ {
return $this->user; return $this->user;
} }
......
...@@ -8,153 +8,24 @@ use Gedmo\Timestampable\Traits\TimestampableEntity; ...@@ -8,153 +8,24 @@ use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**
* @ORM\Entity * TRANSACTION
* @ORM\Table(name="transaction") * Dans l'interface de gestion de son compte professionnel, un prestataire peut effectuer deux types de virements internes, vers un autre prestataire ou vers un adhérent
*/ * Pour ajouter il faut un rôle spécifique:
class Transaction * – Adhérent (paiement numérique avec son compte adhérent)
{ * – Prestataire (entre prestataires et virement vers un compte adhérent)
use TimestampableEntity, * La somme des transactions électroniques sont limitées à un million d'euro par année glissante,
EnablableEntityTrait; * important donc de contrôler au moins le montant global des 365 derniers jours
/**
* @var int
* *
* @ORM\Id * Types de transaction :
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* *
* @ORM\Column(name="type", type="string", length=3) * - PRESTATAIRES => ADHERENTS (Virement vers un adherent)
*/ * - PRESTATAIRES => PRESTATAIRES (Virement entre prestataires)
private $type; * - ADHERENTS => PRESTATAIRES (Paiement numérique)
/**
* @var float
* *
* @ORM\Column(name="montant", type="decimal", precision=7, scale=2) * @ORM\Entity
*/ * @ORM\Table(name="transaction")
private $montant;
/**
* @var null|string
*
* @ORM\Column(name="titre", type="string", length=255, nullable=true)
*/
private $reference;
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="User", inversedBy="transactionsSend", cascade={"persist"})
*/
private $expediteur;
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="User", inversedBy="transactionsReceived", cascade={"persist"})
*/
private $destinataire;
/**
* @return mixed
*/
public function getId(): int
{
return $this->id;
}
/**
* @param User $destinataire
* @return $this
*/
public function setDestinataire(User $destinataire)
{
$this->destinataire = $destinataire;
return $this;
}
/**
* @return User
*/
public function getDestinataire(): User
{
return $this->destinataire;
}
/**
* @param User $expediteur
* @return $this
*/
public function setExpediteur(User $expediteur)
{
$this->expediteur = $expediteur;
return $this;
}
/**
* @return User
*/
public function getExpediteur(): User
{
return $this->expediteur;
}
/**
* @return string
*/
public function getType(): string
{
return $this->type;
}
/**
* @param string $type
* @return Transaction
*/
public function setType(string $type)
{
$this->type = $type;
return $this;
}
/**
* @return float
*/
public function getMontant(): float
{
return $this->montant;
}
/**
* @param float $montant
* @return Transaction
*/
public function setMontant(float $montant)
{
$this->montant = $montant;
return $this;
}
/**
* @return null|string
*/ */
public function getReference(): ?string class Transaction extends Flux
{ {
return $this->reference;
}
/**
* @param null|string $reference
* @return Transaction
*/
public function setReference(?string $reference)
{
$this->reference = $reference;
return $this;
}
} }
...@@ -3,67 +3,32 @@ ...@@ -3,67 +3,32 @@
namespace App\Entity; namespace App\Entity;
use App\Entity\EntityTrait\EnablableEntityTrait; use App\Entity\EntityTrait\EnablableEntityTrait;
use App\Entity\Flux;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity; use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Constraints as Assert;
/** /**
* QUESTION * TRANSFERT
* @ORM\Entity * Les transferts dans la structure sont les flux de billets détenus par les opérateurs.
* @ORM\Table(name="transfert") * Pour ajouter il faut un rôle spécifique :
*/ * – Administrateur (Siège)
class Transfert * – Gestionnaire (Groupe local)
{ * – Comptoir + Vente de monnaie locale
use TimestampableEntity, EnablableEntityTrait; * – Prestataire (Reconversion)
/**
* @var int
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="operateur", type="string", length=20)
*/
private $operateur;
/**
* @var string
* *
* @ORM\Column(name="type", type="string", length=3) * Types de transfert : (Les transferts dans la structure sont les flux de billets détenus par les opérateurs.)
*/
private $type;
/**
* @var string
* QUESTION
* @ORM\Column(name="expediteur", type="string", length=100)
*/
private $expediteur;
/**
* @var string
* QUESTION
* @ORM\Column(name="destinataire", type="string", length=100)
*/
private $destinataire;
/**
* @var float
* *
* @ORM\Column(name="montant", type="decimal", precision=7, scale=2) * - SIEGE => GROUPES LOCAUX (Transfert du siège au groupe)
*/ * - GROUPES LOCAUX => COMPTOIRS (Transfert du groupe au comptoir)
private $montant; * - COMPTOIRS => GROUPES LOCAUX (Transfert du comptoir au groupe)
* - COMPTOIRS => ADHERENTS (Diffusion de monnaie papier auprès des adhérents)
/** * - COMPTOIRS => PRESTATAIRES (Diffusion de monnaie papier auprès des prestataires)
* @var null|string * - PRESTATAIRES => COMPTOIRS (Reconversion)
* *
* @ORM\Column(name="reference", type="string", length=255, nullable=true) * @ORM\Entity()
* @ORM\Table()
*/ */
private $reference; class Transfert extends Flux
{
} }
<?php declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20190118103655 extends AbstractMigration
{
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('CREATE TABLE flux (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, type VARCHAR(3) NOT NULL, expediteur VARCHAR(100) NOT NULL, destinataire VARCHAR(100) NOT NULL, montant NUMERIC(7, 2) NOT NULL, reference VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, discr VARCHAR(255) NOT NULL, INDEX IDX_7252313AA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE lexik_trans_unit (id INT AUTO_INCREMENT NOT NULL, key_name VARCHAR(255) NOT NULL, domain VARCHAR(255) NOT NULL, created_at DATETIME DEFAULT NULL, updated_at DATETIME DEFAULT NULL, UNIQUE INDEX key_domain_idx (key_name, domain), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE lexik_translation_file (id INT AUTO_INCREMENT NOT NULL, domain VARCHAR(255) NOT NULL, locale VARCHAR(10) NOT NULL, extention VARCHAR(10) NOT NULL, path VARCHAR(255) NOT NULL, hash VARCHAR(255) NOT NULL, UNIQUE INDEX hash_idx (hash), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB');
$this->addSql('CREATE TABLE lexik_trans_unit_translations (id INT AUTO_INCREMENT NOT NULL, file_id INT DEFAULT NULL, trans_unit_id INT DEFAULT NULL, locale VARCHAR(10) NOT NULL, content LONGTEXT NOT NULL, created_at DATETIME DEFAULT NULL, updated_at DATETIME DEFAULT NULL, modified_manually TINYINT(1) NOT NULL, INDEX IDX_B0AA394493CB796C (file_id), INDEX IDX_B0AA3944C3C583C9 (trans_unit_id), UNIQUE INDEX trans_unit_locale_idx (trans_unit_id, locale), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB');
$this->addSql('ALTER TABLE flux ADD CONSTRAINT FK_7252313AA76ED395 FOREIGN KEY (user_id) REFERENCES user (id)');
$this->addSql('ALTER TABLE lexik_trans_unit_translations ADD CONSTRAINT FK_B0AA394493CB796C FOREIGN KEY (file_id) REFERENCES lexik_translation_file (id)');
$this->addSql('ALTER TABLE lexik_trans_unit_translations ADD CONSTRAINT FK_B0AA3944C3C583C9 FOREIGN KEY (trans_unit_id) REFERENCES lexik_trans_unit (id)');
$this->addSql('DROP TABLE transaction');
$this->addSql('DROP TABLE transfert');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE lexik_trans_unit_translations DROP FOREIGN KEY FK_B0AA3944C3C583C9');
$this->addSql('ALTER TABLE lexik_trans_unit_translations DROP FOREIGN KEY FK_B0AA394493CB796C');
$this->addSql('CREATE TABLE transaction (id INT AUTO_INCREMENT NOT NULL, expediteur_id INT DEFAULT NULL, destinataire_id INT DEFAULT NULL, type VARCHAR(3) NOT NULL COLLATE utf8mb4_unicode_ci, montant NUMERIC(7, 2) NOT NULL, titre VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, enabled TINYINT(1) NOT NULL, INDEX IDX_723705D1A4F84F6E (destinataire_id), INDEX IDX_723705D110335F61 (expediteur_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('CREATE TABLE transfert (id INT AUTO_INCREMENT NOT NULL, operateur VARCHAR(20) NOT NULL COLLATE utf8mb4_unicode_ci, type VARCHAR(3) NOT NULL COLLATE utf8mb4_unicode_ci, expediteur VARCHAR(100) NOT NULL COLLATE utf8mb4_unicode_ci, destinataire VARCHAR(100) NOT NULL COLLATE utf8mb4_unicode_ci, montant NUMERIC(7, 2) NOT NULL, reference VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, enabled TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('ALTER TABLE transaction ADD CONSTRAINT FK_723705D110335F61 FOREIGN KEY (expediteur_id) REFERENCES user (id)');
$this->addSql('ALTER TABLE transaction ADD CONSTRAINT FK_723705D1A4F84F6E FOREIGN KEY (destinataire_id) REFERENCES user (id)');
$this->addSql('DROP TABLE flux');
$this->addSql('DROP TABLE lexik_trans_unit');
$this->addSql('DROP TABLE lexik_translation_file');
$this->addSql('DROP TABLE lexik_trans_unit_translations');
}
}
<?php declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20190118105955 extends AbstractMigration
{
public function up(Schema $schema) : void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE prestataire ADD partenaire TINYINT(1) NOT NULL');
}
public function down(Schema $schema) : void
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE prestataire DROP partenaire');
}
}
<?php
namespace App\Security\Voter;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
abstract class AbstractVoter extends Voter
{
const LIST = 'list'; // view the list of objects
const VIEW = 'view'; // view the detail of one object
const CREATE = 'create'; // create a new object
const EDIT = 'edit'; // update an existing object
const DELETE = 'delete'; // delete an existing object
const EXPORT = 'export'; // (for the native Sonata export links)
const ALL = 'all'; // grants LIST, VIEW, CREATE, EDIT, DELETE and EXPORT
private $decisionManager;
public function __construct(AccessDecisionManagerInterface $decisionManager)
{
$this->decisionManager = $decisionManager;
}
protected static function supportsAttribute($attribute)
{
// Est-ce que l'action demandée existe
if (!in_array($attribute, array(self::LIST, self::VIEW, self::CREATE, self::EDIT, self::DELETE, self::EXPORT, self::ALL))) {
return false;
}
return true;
}
abstract protected function voteOnAttribute($attribute, $subject, TokenInterface $token);
}
...@@ -3,29 +3,17 @@ ...@@ -3,29 +3,17 @@
namespace App\Security\Voter; namespace App\Security\Voter;
use App\Entity\User; use App\Entity\User;
use App\Security\Voter\AbstractVoter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface; use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class UserVoter extends Voter class UserVoter extends AbstractVoter
{ {
const ADD = 'add';
const GET = 'get';
const EDIT = 'edit';
const LIST = 'list';
const REMOVE = 'remove';
private $decisionManager;
public function __construct(AccessDecisionManagerInterface $decisionManager)
{
$this->decisionManager = $decisionManager;
}
protected function supports($attribute, $subject) protected function supports($attribute, $subject)
{ {
// Est-ce que l'action demandée existe // Est-ce que l'action demandée existe
if (!in_array($attribute, array(self::ADD, self::GET, self::EDIT, self::REMOVE))) { if (!parent::supportsAttribute($attribute)) {
return false; return false;
} }
...@@ -47,32 +35,42 @@ class UserVoter extends Voter ...@@ -47,32 +35,42 @@ class UserVoter extends Voter
} }
// Les admins peuvent tout faire ! // Les admins peuvent tout faire !
if ($this->decisionManager->decide($token, array('ROLE_SUPER_ADMIN', 'ROLE_ADMIN'))) { if ($this->decisionManager->decide($token, array('ROLE_SUPER_ADMIN', 'ROLE_ADMIN', 'ROLE_ADMIN_SIEGE'))) {
return true; return true;
} }
switch ($attribute) { switch ($attribute) {
case self::ADD: case self::LIST:
return $this->canAdd($subject, $user); return $this->canList($subject, $user);
case self::GET: case self::VIEW:
return $this->canGet($subject, $user); return $this->canView($subject, $user);
case self::CREATE:
return $this->canCreate($subject, $user);
case self::EDIT: case self::EDIT:
return $this->canEdit($subject, $user); return $this->canEdit($subject, $user);
case self::REMOVE: case self::DELETE:
return $this->canRemove($subject, $user); return $this->canDelete($subject, $user);
case self::EXPORT:
return $this->canExport($subject, $user);
case self::ALL:
return $this->canAll($subject, $user);
} }
throw new \LogicException('This code should not be reached!'); throw new \LogicException('This code should not be reached!');
} }
private function canAdd(User $subject, User $user) private function canList(User $subject, User $user)
{ {
if ($this->decisionManager->decide($token, array('ROLE_ADHERENT'))) { // Only ADMIN can list users so already return true before
return false; return false;
} }
private function canView(User $subject, User $user)
{
// if ($this->decisionManager->decide($token, array('ROLE_ADHERENT'))) {
} }
private function canGet(User $subject, User $user) private function canCreate(User $subject, User $user)
{ {
} }
...@@ -80,7 +78,15 @@ class UserVoter extends Voter ...@@ -80,7 +78,15 @@ class UserVoter extends Voter
{ {
} }
private function canRemove(User $subject, User $user) private function canDelete(User $subject, User $user)
{
}
private function canExport(User $subject, User $user)
{
}
private function canAll(User $subject, User $user)
{ {
} }
} }
...@@ -212,6 +212,9 @@ ...@@ -212,6 +212,9 @@
"kriswallsmith/buzz": { "kriswallsmith/buzz": {
"version": "v0.16.1" "version": "v0.16.1"
}, },
"lexik/translation-bundle": {
"version": "v4.0.13"
},
"liip/imagine-bundle": { "liip/imagine-bundle": {
"version": "1.8", "version": "1.8",
"recipe": { "recipe": {
...@@ -383,6 +386,9 @@ ...@@ -383,6 +386,9 @@
"sonata-project/exporter": { "sonata-project/exporter": {
"version": "1.9.1" "version": "1.9.1"
}, },
"sonata-project/intl-bundle": {
"version": "2.5.0"
},
"sonata-project/media-bundle": { "sonata-project/media-bundle": {
"version": "3.13", "version": "3.13",
"recipe": { "recipe": {
...@@ -392,6 +398,15 @@ ...@@ -392,6 +398,15 @@
"ref": "e25412e53b20827db07abb6f2aa0b8e4d26c284c" "ref": "e25412e53b20827db07abb6f2aa0b8e4d26c284c"
} }
}, },
"sonata-project/translation-bundle": {
"version": "2.3",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "master",
"version": "2.3",
"ref": "00e821cb362f00c6893f7183311893267330ecfe"
}
},
"sonata-project/user-bundle": { "sonata-project/user-bundle": {
"version": "4.2.3" "version": "4.2.3"
}, },
......
{#<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block lexik_title %}{% endblock %}</title>
{% block lexik_stylesheets %}
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ asset('bundles/lexiktranslation/ng-table/ng-table.min.css') }}">
{% endblock %}
</head>
<body>
{% block lexik_flash_message %}
<div class="container">
<div class="row">
<div class="col-md-12">
{% set flashes = app.session.flashbag.all() %}
{% if flashes | length > 0 %}
{% for type, messages in flashes %}
{% for message in messages %}
<div class="alert alert-{{ type }}">{{ message }}</div>
{% endfor %}
{% endfor %}
{% endif %}
</div>
</div>
</div>
{% endblock lexik_flash_message %}
{% block lexik_content '' %}
{% block lexik_javascript_footer %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="{{ asset('bundles/lexiktranslation/ng-table/ng-table.min.js') }}"></script>
{% endblock %}
</body>
</html>#}
{% extends sonata_admin.adminPool.templates.layout %}
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ asset('bundles/lexiktranslation/ng-table/ng-table.min.css') }}">
{% endblock %}
{% block content %}
<div class="traductions">
{% block lexik_content %}
{% endblock %}
</div>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.9/angular.min.js"></script>
<script src="{{ asset('bundles/lexiktranslation/ng-table/ng-table.min.js') }}"></script>
{% block lexik_javascript_footer %}{% endblock %}
{% endblock %}
...@@ -212,6 +212,37 @@ file that was distributed with this source code. ...@@ -212,6 +212,37 @@ file that was distributed with this source code.
</ul> </ul>
</div> </div>
{% endif %} {% endif %}
<div class="navbar-custom-menu">
<ul class="nav navbar-nav">
{% block sonata_top_nav_menu_locale_block %}
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-flag fa-fw" aria-hidden="true"></i>
<i class="fa fa-caret-down" aria-hidden="true"></i>
</a>
<div class="dropdown-menu multi-column dropdown-add">
<div class="container-fluid">
<div class="row">
<ul class="dropdown-menu">
<li role="presentation" class="dropdown-header">
<i class="fa fa-language"></i>
{{ 'languages'|trans({}, 'SonataTranslationBundle') }}
</li>
{% for locale in sonata_translation_locales %}
<li role="presentation" class="{{ app.request.locale == locale ? 'active' : '' }}">
<a role="menuitem" tabindex="-1" href="{{ path('sonata.translation.locale', {'locale': locale}) }}">
{{ locale|language(locale)|capitalize }}
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</li>
{% endblock %}
</ul>
</div>
{% endblock %} {% endblock %}
</nav> </nav>
{% endblock sonata_nav %} {% endblock sonata_nav %}
......
layout.logged_in_as: 'Se connecter en tant que' layout:
layout.logout: 'Se déconnecter' logged_in_as: 'Se connecter en tant que'
layout.login: 'Se connecter' logout: 'Se déconnecter'
security.login.username: Email login: 'Se connecter'
security.login.password: 'Mot de passe' security:
security.login.remember_me: 'Se souvenir de moi' login:
security.login.submit: 'Se connecter' username: Email
form.current_password: 'Mot de passe actuel' password: 'Mot de passe'
form.new_password: 'Nouveau mot de passe' remember_me: 'Se souvenir de moi'
form.new_password_confirmation: 'Confirmer le mot de passe' submit: 'Se connecter'
change_password.submit: Confirmer form:
current_password: 'Mot de passe actuel'
new_password: 'Nouveau mot de passe'
new_password_confirmation: 'Confirmer le mot de passe'
change_password:
submit: Confirmer
app.admin.group:
adherent: Adherent
prestataire: Prestataire
groupe: Groupe
app.admin.group:
adherent: Member
prestataire: Recipient
groupe: Group
app:
admin.group:
adherent: Adherent
prestataire: Prestataire
groupe: Groupe
groups: Roles
Commentaires: Comments
app:
admin.group:
adherent: Member
prestataire: Recipient
groupe: Group
move_to_bottom: 'Tout en bas'
move_down: '+ bas'
move_up: '+ haut'
move_to_top: 'Tout en haut'
Commentaires: Commentaires
app:
admin.group:
adherent: Adherent
prestataire: Prestataire
groupe: Groupe
...@@ -19,6 +19,7 @@ Encore ...@@ -19,6 +19,7 @@ Encore
* and one CSS file (e.g. app.css) if you JavaScript imports CSS. * and one CSS file (e.g. app.css) if you JavaScript imports CSS.
*/ */
.addEntry('app', './assets/js/app.js') .addEntry('app', './assets/js/app.js')
.addEntry('admin', './assets/js/admin.js')
//.addEntry('page1', './assets/js/page1.js') //.addEntry('page1', './assets/js/page1.js')
//.addEntry('page2', './assets/js/page2.js') //.addEntry('page2', './assets/js/page2.js')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment