Silex



Principaux fichiers

composer.json
{
  "require": {
    "php": ">=7.0.4",
    "silex/silex": "@stable",
    "silex/web-profiler": ">=2.0",
    "symfony/http-kernel": ">=3.1",
    "symfony/routing": ">=2.8|>=3.0",
    "symfony/asset": ">=2.8|3.0.*",
    "symfony/browser-kit": ">=2.8|3.0.*",
    "symfony/class-loader": ">=2.8|3.0.*",
    "symfony/config": ">=2.8|3.0.*",
    "symfony/console": ">=2.8|3.0.*",
    "symfony/css-selector": ">=2.8|3.0.*",
    "symfony/debug": ">=2.8|3.0.*",
    "symfony/var-dumper": ">=2.8|3.0.*",
    "symfony/finder": ">=2.8|3.0.*",
    "symfony/form": ">=2.8|3.0.*",
    "symfony/monolog-bridge": ">=2.8|3.0.*",
    "symfony/process": ">=2.8|3.0.*",
    "symfony/security": ">=2.8|3.0.*",
    "symfony/translation": ">=2.8|3.0.*",
    "symfony/twig-bridge": ">=2.8|3.0.*",
    "symfony/validator": ">=2.8|3.0.*",
    "symfony/yaml": ">=2.8|3.0.*",
    "symfony/http-foundation": ">=2.8|3.0.*",
    "deralex/yaml-config-service-provider": "2.0.x-dev",
    "phpmailer/phpmailer": ">=5.2",
    "spipu/html2pdf": "^4.6",
    "paypal/rest-api-sdk-php": "*",
    "stripe/stripe-php": "@stable"
  }
}
app.php
use Silex\Application;
use Silex\Provider\TwigServiceProvider;
use Silex\Provider\RoutingServiceProvider;
use Silex\Provider\ValidatorServiceProvider;
use Silex\Provider\ServiceControllerServiceProvider;
use Silex\Provider\HttpFragmentServiceProvider;
use Silex\Provider\SessionServiceProvider;
use Silex\Provider\SecurityServiceProvider;
use Silex\Provider\CsrfServiceProvider;
use Silex\Provider\RememberMeServiceProvider;
use Silex\Provider\VarDumperServiceProvider;
use Silex\Provider\FormServiceProvider;
use Silex\Provider\TranslationServiceProvider;
use DerAlex\Pimple\YamlConfigServiceProvider;
use Manager\ManagerProvider;

$app = new Application();
$app->register(new RoutingServiceProvider());
$app->register(new ValidatorServiceProvider());
$app->register(new ServiceControllerServiceProvider());
$app->register(new TwigServiceProvider());
$app->register(new HttpFragmentServiceProvider());
$app->register(new SessionServiceProvider());
$app->register(new FormServiceProvider());
$app->register(new ManagerProvider($app));
$app->register(new YamlConfigServiceProvider(__DIR__ . '/../app/settings.yml'));
$app->register(new SecurityServiceProvider(), [
    'security.firewalls' => [
        'default' => [
            'pattern'   => '^.*$',
            'anonymous' => true,
            'form'      => [
                'login_path' => '/login',
                'check_path' => '/login_check'
            ],
            'logout'    => [
                'logout_path' => '/logout',
                'target_url' => '/annuaire'
            ],
            'users'     => function($app) {
                return new Authenticate\UserProvider( $app['manager.user'] );
            },
            'remember_me' => [
                'key'                => $app['config']['secret']['rememberme'],
                'name'               => 'PROXIDATA',
                'lifetime'           => 604800,
                'path'               => '/',
                'httponly'           => true,
                'always_remember_me' => false,
            ],
        ],
    ],
    'security.role_hierarchy' => [
        'ROLE_ADMIN' => [
            'ROLE_USER',
        ],
        'ROLE_SUPER_ADMIN' => [
            'ROLE_USER',
            'ROLE_ADMIN',
            'ROLE_ALLOWED_TO_SWITCH'
        ]
    ],
    'security.access_rules' => [
        [ '^/admin', 'ROLE_ADMIN' ],
        [ '^/account', 'ROLE_USER' ],
        [ '^.*$', 'IS_AUTHENTICATED_ANONYMOUSLY' ]
    ]
]);
$app->register(new CsrfServiceProvider());
$app->register(new RememberMeServiceProvider());
$app->register(new VarDumperServiceProvider());
$app->register(new TranslationServiceProvider(), array(
    'translator.messages' => array(),
    'locale' => 'fr',
));

$app['twig'] = $app->extend('twig', function ($twig, $app) {
    // add custom globals, filters, tags, ...
    return $twig;
});

$app['security.authentication.success_handler.default'] = function($app) {
    return new Model\CustomAuthenticationSuccessHandler($app['security.http_utils'], 
    array(), $app);
};

return $app;
index.php
ini_set('display_errors', 1);

require_once __DIR__.'/../vendor/autoload.php';

$app = require __DIR__.'/../src/app.php';

require __DIR__.'/../config/prod.php';
require __DIR__.'/../src/controllers.php';

$app->run();
index_dev.php
use Symfony\Component\Debug\Debug;

// This check prevents access to debug front controllers that are deployed by accident to production servers.
if (isset($_SERVER['HTTP_CLIENT_IP'])
    || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
    || !in_array(@$_SERVER['REMOTE_ADDR'], array('127.0.0.1', 'fe80::1', '::1'))
) {
    header('HTTP/1.0 403 Forbidden');
    exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}

require_once __DIR__.'/../vendor/autoload.php';

Debug::enable();

$app = require __DIR__.'/../src/app.php';

require __DIR__.'/../config/dev.php';
require __DIR__.'/../src/controllers.php';

$app->run();
Use
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

use Model\Filtres;
...
Téléchargement de fichiers
$app->get('/fichier/{type}/{folder}/{file}', function ($type, $folder, $file) use ($app) {

    $path = __DIR__."/../files/$type/$folder/$file";

    if (!file_exists($path)) {
        $app->abort(404, 'Ce fichier n\'existe pas.');
    }

    //header("Content-Disposition:attachment; filename='test2.csv'");
    //header("Content-Disposition:attachment;");

    return $app
        ->sendFile($path)
        ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, basename($path))
    ;

})->bind('getfile');
Pages d'erreurs
$app->error(function (\Exception $e, $code) use ($app) {

    if ( method_exists($e, 'getStatusCode') && is_callable([$e, 'getStatusCode']) ) {

        $error = $e->getStatusCode();

        // 404.twig, or 40x.twig, or 4xx.twig, or error.twig
        $templates = [
            'errors/'.$error.'.twig',
            'errors/'.substr($error, 0, 2).'x.twig',
            'errors/'.substr($error, 0, 1).'xx.twig',
            'errors/default.twig',
        ];

        return new Response(
            $app['twig']
                ->resolveTemplate($templates)
                ->render([
                    'code' => $error,
                    'msg' => $e->getMessage(),
                ])
        );
    }

});
class Form

Use
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\CountryType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;
...
Charger les infos du current user
 private $user;
  private $form;

  private $email;
  private $firstname;
  private $lastname;
  private $societe;
  private $liv_pays;
  private $liv_ville;
  private $liv_cp;
  private $liv_adresse;
  private $fac_pays;
  private $fac_ville;
  private $fac_cp;
  private $fac_adresse;

  public function __construct(Application $app)
  {
    $this->email       = "";
    $this->firstname   = "";
    $this->lastname    = "";
    $this->societe     = "";
    $this->phone       = "";
    $this->liv_pays    = "";
    $this->liv_ville   = "";
    $this->liv_cp      = "";
    $this->liv_adresse = "";
    $this->fac_pays    = "";
    $this->fac_ville   = "";
    $this->fac_cp      = "";
    $this->fac_adresse = "";
    $this->optin       = "FALSE";
    $this->renew       = "FALSE";

    $token = $app['security.token_storage']->getToken();
    if (null !== $token) {
      $this->user = $token->getUser();

      if(is_object($this->user)) {
        $this->email       = $this->user->getUsername();
        $this->firstname   = $this->user->getFirstname();
        $this->lastname    = $this->user->getLastname();
        $this->societe     = $this->user->getSociete();
        $this->phone       = $this->user->getPhone();
        $this->liv_pays    = null === $this->user->getLivraisonPays() ? 'FR' : $this->user->getLivraisonPays();
        $this->liv_ville   = $this->user->getLivraisonVille();
        $this->liv_cp      = $this->user->getLivraisonCp();
        $this->liv_adresse = $this->user->getLivraisonAdresse();
        $this->fac_pays    = null === $this->user->getFacturationPays() ? 'FR' : $this->user->getFacturationPays();
        $this->fac_ville   = $this->user->getFacturationVille();
        $this->fac_cp      = $this->user->getFacturationCp();
        $this->fac_adresse = $this->user->getFacturationAdresse();
        $this->optin       = $this->user->getOptin();
        $this->renew       = $this->user->getRenew();
      }
    }

    $this->form = $app['form.factory']->createBuilder(FormType::class);
  }
FormType
$this->form = $app['form.factory']->createBuilder(FormType::class);
TextType
public function addFirstname() {
  $this->form->add('firstname', TextType::class, [
    'required' => true,
    'attr' => [
      'placeholder' => "Prénom",
    ],
    'data' => $this->firstname,
    'constraints' => [
      new Assert\NotBlank(['message' => "Ce champ est obligatoire."]),
      new Assert\Length([
        'min' => 2,
        'minMessage' => 'Le prénom doit comporter plus de {{ limit }} caractères.',
      ]),
      new Assert\Regex([
        'pattern' => '/^[-\' \p{L}]+$/u',
        'match'   => true,
        'message' => 'Le prénom ne peux contenir que lettres et traits d’union.',
      ]),
    ]
  ]); return $this;
}
EmailType
public function addEmail() {
  $this->form->add('email', EmailType::class, [
    'required' => true,
    'attr' => [
      'placeholder' => "Email",
    ],
    'data' => $this->email,
    'constraints' => [
      new Assert\NotBlank(['message' => "Ce champ est obligatoire."]),
      new Assert\Length([
        'min' => 5,
        'minMessage' => 'L\'email doit comporter plus de {{ limit }} caractères.',
      ]),
      new Assert\Email([
        'message' => "L'email {{ value }} n'est pas valide.",
      ]),
    ]
  ]); return $this;
}
PasswordType
public function addOldPassword() {
  $this->form->add('oldPassword', PasswordType::class, [
    'required' => true,
    'attr' => [
      'placeholder' => "Mot de passe actuel"
    ],
    'constraints' => [
      new Assert\NotBlank(['message' => "Ce champ est obligatoire."]),
      new UserPassword([
        'message' => 'Valeur incorrecte pour votre mot de passe actuel.',
      ]),
    ],
  ]); return $this;
}
RepeatedType
public function addPlainPassword() {
  $this->form->add('plainPassword', RepeatedType::class, [
    'type' => PasswordType::class,
    'required' => true,
    'first_options'  => [
      'label' => 'Mot de passe',
      'attr' => ['placeholder' => 'Mot de passe']
    ],
    'second_options' => [
      'label' => 'Confirmez le mot de passe',
      'attr' => ['placeholder' => 'Confirmez le mot de passe']
    ],
    'constraints' => [
      new Assert\NotBlank(['message' => "Ce champ est obligatoire."]),
      new Assert\Length([
        'min' => 8,
        'minMessage' => 'Le mot de passe doit comporter plus de {{ limit }} caractères.',
      ]),
    ],
    'invalid_message' => 'Le mot de passe doit être identique.',
    'options' => ['attr' => [
      'class' => 'password-field',
      'placeholder' => "Mot de passe"
    ]],
  ]); return $this;
}
NumberType
public function addLivraisonCP() {
  $this->form->add('liv_cp', NumberType::class, [
    'data' => $this->liv_cp,
    'required' => true,
    'invalid_message' => "Le code postal saisi n'est pas correct.",
    'attr' => [
      'placeholder' => "Code Postal",
    ],
    'constraints' => [
      new Assert\NotBlank(['message' => "Ce champ est obligatoire."]),
      new Assert\Regex([
        'pattern' => '/^[0-9]{1,}$/',
        'match'   => true,
        'message' => 'Le code postal doit être une suite de chiffres.',
      ]),
    ]
  ]); return $this;
}
TextareaType
public function addMessage() {
  $this->form->add('message', TextareaType::class, [
    'required' => true,
    'attr' => [
      'placeholder' => "Message",
    ],
    'constraints' => [
      new Assert\NotBlank(['message' => "Ce champ est obligatoire."]),
    ]
  ]); return $this;
}
CountryType
public function addLivraisonPays() {
  $this->form->add('liv_pays', CountryType::class, [
    'data' => $this->liv_pays,
    'required' => true,
    'attr' => [
      'placeholder' => "Pays"
    ]
  ]); return $this;
}
CheckboxType
public function addRenew() {
  $this->form->add('renew', CheckboxType::class, [
    'required' => false,
    'data'     => $this->renew,
    'label'    => "Renouvellement mensuel automatique.",
  ]); return $this;
}
ChoiceType
public function addPaiementType() {
  $this->form->add('paiementType', ChoiceType::class, [
    'choices' => [
      'virement'  => 'virement',
      'cheque'    => 'cheque',
      'paypal'    => 'paypal',
      'paypal-cb' => 'paypal-cb',
      'cb'        => 'cb'
    ],
    'multiple' => false,
    'expanded' => true,
    'data'     => 'virement'
  ]); return $this;
}