Liste de toutes les commandes consoles disponibles
php bin/console
php bin/console
Vérifier qu'on peut exécuter des commandes Php avec la console
php -v
Si le message "php n'est pas reconnu en tant que commande interne" apparaît, il faut ajouter le répertoire où se trouve la commande php à la variable d'environnement PATH :
Aller dans Démarrer > Panneau de configuration > Système et sécurité > Système > Paramètres systèmes avancés > Variables d'environnement.
Dans le panneau "Variables systèmes", double-cliquer sur l'entrée Path.
Dans "Valeur de la variable", ajouter le répertoire Php : ;C:\wamp\bin\php\php5.5.12
Confirmer en cliquant sur OK.
Redémarrer l'ordinateur et exécuter à nouveau la commande :
php -v
La version de Php apparaît :
Php 5.5.12 (...) Copyright (...) Zend engine (...)
Vérifier qu'on a Git
git version
Si ce n'est pas le cas, aller sur :
https://git-scm.com/
Télécharger et exécuter l'installeur.
Afficher la documentation Git
git help
Ouvrir une fenêtre de commandes dans le dossier www pour y télécharger le fichier composer.phar
php -r "eval('?>'.file_get_contents('http://getcomposer.org/installer'));
Créer un dossier vide dans www qui va contenir le projet dont le nom est (par exemple) "site_stretching"
Ouvrir une fenêtre de commandes dans www.
Pour télécharger une application complète Symfony exécuter :
php composer.phar create-project symfony/framework-standard-edition site_stretching
Laisser charger puis faire ok pour tout (database et mailer) sauf pour database_name (indiquer le nom "stretching" par exemple)
Installer les ressources dans le dossier web
Rendre disponibles les nouveaux fichiers JS et CSS du bundle
Charger les fichiers CSS, copier les fichiers statiques des bundles dans web (utiliser --symlink pour des liens symboliques à la place de copies)
php bin/console assets:install
Vérifier que l'application tourne
http://localhost/site_stretching/web/
Solution 1 pour vérifier la configuration et suivre les indications
http://localhost/site_stretching/web/config.php
Solution 2 pour vérifier la configuration et suivre les indications
php bin/symfony_requirements
Vérifier l'environnement de développement
http://localhost/site_stretching/web/app_dev.php/
Vérifier l'environnement de production
http://localhost/site_stretching/web/app.php
Vérifier le profiler
http://localhost/site_stretching/web/app_dev.php/_profiler
Ouvrir une fenêtre de commandes dans le dossier site_stretching
php bin/console generate:bundle
Multiples applications : yes
Namespace : Sofictif/StretchingBundle
Bundle name : SofictifStretchingBundle
Target directory : src
Configuration format : annotation
Retourner dans l'environnement de développement
http://localhost/site_stretching/web/app_dev.php/
Que s'est-il passé ?
1. Le Kernel a chargé le bundle :
Dans le fichier app/AppKernel.php est apparue la ligne :
new Sofictif\StretchingBundle\SofictifStretchingBundle(),
2. Le routing a pris en compte le bundle :
Dans le fichier app/config/routing.yml sont apparues les lignes :
sofictif_stretching:
resource: "@SofictifStretchingBundle/Controller/"
type: annotation
prefix: /
3. Dans le dossier src a été créé un dossier "Sofictif" qui comporte un sous-dossier "StretchingBundle".
Dans ce dernier a été créée une arborescence type dans laquelle on peut travailler (dont les dossiers "Controller", "DependencyInjection", "Entity", "Repository", "Resources", "Tests", et un fichier "SofictifStrectchingBundle.php")
Supprimer le dossier /src/Appbundle
Supprimer du fichier /app/AppKernel.php la ligne :
new AppBundle\AppBundle(),
Supprimer les chemins du bundle dans /app/config/routing.yml qui correspondent à ces lignes :
app:
resource: "@AppBundle/Controller/"
type: annotation
Nettoyer le cache :
php bin/console cache:clear
Retourner dans l'environnement de développement
http://localhost/site_stretching/web/app_dev.php/
Ils sont regroupés sur http://knpbundles.com.
Exemples de bundles :
Pour une entité "Image", créer une base de donnée vide dans PhpMyadmin, puis exécuter dans la console :
php bin/console doctrine:generate:entity
shortcutname : SofictifStretchingBundle:Image
configuration format : annotation
Si on ne veut pas utiliser la console pour générer les propriétés, cliquer sur "entrée" tout le temps, ensuite entrer "à la main" les paramètres dans le fichier de l'entité
Que s'est-il passé ?
Dans le dossier /src/Sofictif/StretchingBundle/Entity a été créé la classe Image.php, fichier php de l'entité Image.
php bin/console doctrine:generate:entities SofictifStretchingBundle:Image
Que s'est-il passé ?
1. Les getters et setters ont été générés dans /src/Sofictif/StretchingBundle/Entity/Image.php
Un fichier Image.php~ reste à côté de Image.php, il contient le fichier initial qu'on peut supprimer si tout est ok.
2. Un fichier ImageRepository.php a été créé dans /src/Sofictif/StretchingBundle/Repository/
php bin/console doctrine:generate:entities SofictifStretchingBundle
http://symfony.com/doc/current/cookbook/doctrine/reverse_engineering.html
OneToOne, Unidirectional
Dans l'entité Book.php :
/**
* @ORM\OneToOne(targetEntity="Illustration", cascade={"persist"})
* @ORM\JoinColumn(name="illustration_id", referencedColumnName="id")
*/
private $illustration;
OneToOne, Bidirectional
Dans l'entité Book.php :
/**
* @ORM\OneToOne(targetEntity="Illustration", inversedBy="book", cascade={"persist"})
* @ORM\JoinColumn(name="illustration_id", referencedColumnName="id")
*/
private $illustration;
Dans l'entité Illustration.php :
/**
* @ORM\OneToOne(targetEntity="Book", mappedBy="illustration")
*/
private $book;
ManyToOne
Dans l'entité Book.php :
/**
* @ORM\ManyToOne(targetEntity="Collection", inversedBy="books", cascade={"persist"})
* @ORM\JoinColumn(name="collection_id", referencedColumnName="id")
*/
private $collection;
Dans l'entité Collection.php :
/**
* @ORM\OneToMany(targetEntity="Book", mappedBy="collection", cascade={"persist"})
*/
private $books;
ManyToMany
Dans l'entité Family.php :
/**
* @ORM\ManyToMany(targetEntity="Person", mappedBy="families", cascade={"persist"})
*/
private $persons;
Dans l'entité Person.php :
/**
* @ORM\ManyToMany(targetEntity="Family", inversedBy="persons", cascade={"persist"})
* @ORM\JoinTable(name="persons_families")
*/
private $families;
1. Supprimer manuellement tous les fichiers dans les dossiers : entity, repository, form
2. Dans phpmyadmin supprimer constrainte la foreign key :
Afficher la structure de la table parente, cliquer sur "vue relationnelle"
À droite du nom du champ, garder le même nom de base de donnée mais mettre des valeurs vides pour la table et le champ
Au lieu d'avoir audio_id podcasts audio id
Mettre audio_id podcasts rien rien
3. Supprimer manuellement les champs et tables concernés
Vérifier les informations de configuration sur la base de données dans le fichier app/config/parameters.yml
php bin/console doctrine:database:create
Pour les entités complètes
php bin/console doctrine:schema:create --dump-sql
Pour les éléments modifiés des entitiés
php bin/console doctrine:schema:update --dump-sql
Envoyer les modifications SQL à la base de données
php bin/console doctrine:schema:update --force
php bin/console doctrine:mapping:info
php bin/console doctrine:database:drop --force
http://symfony.com/doc/current/bundles/SensioGeneratorBundle/commands/generate_doctrine_crud.html
php bin/console generate:doctrine:crud
The entity shortcut name : SofictifStretchingBundle:Image
Do you want to generate the "write" actions ? yes
Configuration format : annotation
Route prefix : image
Du you confirm ? yes
Que s'est-il passé ?
1. Le contrôleur est généré dans src/Sofictif/StretchingBundle/Controller.
Il liste tous les enregistrements, en affiche un en fonction de son id, crée, modifie et supprime un nouvel enregistrement (actions list, show, new, update, delete)
2. Les vues sont créées dans le dossier app/Resources/views.
3. Le type de formulaire est généré dans src/Sofictif/StretchingBundle/Form
Déplacer les vues dans le bundle Sofictif
Déplacer le dossier des vues dans le dossier src/Sofictif/StretchingBundle/Resources/views
Dans chaque vue, faire hériter de la vue de base du bundle :
{% extends 'SofictifStretchingBundle::base.html.twig' %}
Dans le contrôleur, modifier chaque lien des rendus des vues :
return $this->render('SofictifStretchingBundle::image/index.html.twig', array(...));
Télécharger le pack minimum
Retour simple
use Symfony\Component\HttpFoundation\Response;
return new Response('My training');
Retour avec html
use Symfony\Component\HttpFoundation\Response;
return new Response(
'<html><body>Duration: '.$secondes.'</body></html>'
);
Retour dans un template
return $this->render('SofictifStretchingBundle::body/upper.html.twig', array(
'member' => $arms,
'duration' => $secondes,
));
Redirection vers une route d'un contrôleur
return $this->redirectToRoute('home');
Redirection vers une route d'un contrôleur avec des paramètres
return $this->redirectToRoute('body_show', array('member' => 'legs'));
Forward à un autre contrôleur
$response = $this->forward('SofictifStretchingBundle:Body:lower', array(
'member' => $legs,
'duration' => $secondes,
));
return $response;
public function bodyAction($member, $duration) {}
Redirection permanente 301
return $this->redirectToRoute('home', array(), 301);
Redirection externe
return $this->redirect('http://symfony.com/doc');
La méthode createQueryBuilder() retourne une instance de QueryBuilder qui permet de construire une Query.
Faire une requête sur l'entité gérée par ce repository.
public function findAll() {
return $this
->createQueryBuilder('a')
->orderBy('a.name', 'ASC')
->getQuery()
->getResult()
;
}
Autre solution :
public function findAll() {
return $this->findBy(array(), array('name' => 'ASC'));
}
php bin/console cache:clear
Supprimer physiquement les fichiers du dossier var > cache > dev
Supprimer physiquement les fichiers du dossier var > cache > prod
php bin/console cache:clear --env=prod
Pas besoin de le faire si on génère les contrôleurs en ligne de commande.
php bin/console doctrine:generate:form SofictifStretchingBundle:Categorie
TextType
use Symfony\Component\Form\Extension\Core\Type\TextType;
$builder->add('title', TextType::class, array(
'required' => true,
'label' => 'Titre',
));
Correspondance dans src > Sofictif > StretchingBundle > Entity > Position.php
* @ORM\Column(type="string", length=255)
TextareaType
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
$builder->add('description', TextareaType::class, array(
'required' => true,
'label' => 'Description',
));
Correspondance dans src > Sofictif > StretchingBundle > Entity > Position.php
* @ORM\Column(type="text", nullable=true)
MoneyType
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
$builder->add('sellingprice', MoneyType::class, array(
'required' => true,
'label' => 'Prix',
));
Correspondance dans src > Sofictif > StretchingBundle > Entity > Position.php
* @ORM\Column(type="float", nullable=true)
TimeType
use Symfony\Component\Form\Extension\Core\Type\TimeType;
$builder->add('startime', TimeType::class, array(
'required' => false,
'label' => 'Heure de début',
'input' => 'datetime',
'widget' => 'choice',
'placeholder' => array(
'hour' => 'Heure', 'minute' => 'Minute', 'second' => 'Second',
)
));
Correspondance dans src > Sofictif > StretchingBundle > Entity > Position.php
* @ORM\Column(name="startime", type="time", nullable=true)
ChoiceType
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$builder->add('acquired', ChoiceType::class, array(
'required' => true,
'label' => 'Acquis',
'choices' => array(
'oui' => true,
'non' => false,
),
'placeholder' => false,
'multiple' => false,
'expanded' => true,
));
Correspondance dans src > Sofictif > StretchingBundle > Entity > Position.php
* @ORM\Column(type="boolean", options={"default":false})
FileType
use Symfony\Component\Form\Extension\Core\Type\FileType;
$builder->add('file', FileType::class, array(
'required' => false,
'label' => 'Fichier',
'data_class' => null,
));
Correspondance dans src > Sofictif > StretchingBundle > Entity > Position.php
* @ORM\Column(name="file", type="string", length=255, nullable=true)
EntityType (si relation avec une entité)
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
$builder->add('family', EntityType::class, array(
'required' => false,
'label' => 'Famille',
'class' => 'SofictifStretchingBundle:Family',
'multiple' => true,
'expanded' => true,
'placeholder' => false,
'choice_label' => 'name',
));
Correspondance dans src > Sofictif > StretchingBundle > Entity > Position.php
* @ORM\OneToOne(targetEntity="Member", cascade={"persist"})
* @ORM\JoinColumn(name="holder_id", referencedColumnName="id")
EntityType avec label multiple
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
$builder->add('family', EntityType::class, array(
'required' => false,
'label' => 'Famille',
'class' => 'SofictifStretchingBundle:Family',
'multiple' => true,
'expanded' => true,
'choice_label' => function ($member) {
return $member->getName().' '.$member->getSurname();
},
));
EntityType avec label multiple et affichage dans un ordre particulier (si relation avec une entité)
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
$builder->add('family', EntityType::class, array(
'required' => false,
'label' => 'Famille',
'class' => 'SofictifStretchingBundle:Family',
'multiple' => true,
'expanded' => true,
'choice_label' => function ($member) {
if ($member->getType() == 0) {
$type = 'femme';
} else {
$type = 'homme';
}
return $member->getName().' '.$member->getSurname().' ('.$type.')';
},
'query_builder' => function (EntityRepository $family) {
return $family->createQueryBuilder('f')
->orderBy('f.id, f.name', 'ASC');
->add('where', 'f.registration = 1 and f.id != 12');
},
));
Récupérer l’id d’un objet de formulaire et le réutiliser dans le QueryBuilder
public function buildForm(FormBuilderInterface $builder, array $options)
{
$idConferenceSpeaker = $builder->getData()->getSpeaker()->getId();
$builder
->add('additionalspeakers', EntityType::class, array(
'required' => false,
'label' => false,
'class' => 'SofictifPodcastBundle:Speaker',
'choice_label' => function ($speaker) {
return $speaker->getSurname().' '.$speaker->getName();
},
'query_builder' => function (EntityRepository $speaker) use ($idConferenceSpeaker) {
return $speaker->createQueryBuilder('s')
->add('where', 's.id != '.$idConferenceSpeaker)
->orderBy('s.surname', 'ASC');
},
'multiple' => true,
'expanded' => true,
'placeholder' => false,
))
;
}
Passer un paramètre du controller au formulaire
Dans le controller
$type = $em->getRepository('SofictifStretchingBundle:Type')->findOneBySlug('slug');
$form = $this->createForm('Sofictif\StretchingBundle\Form\CategorieMenusSortableType', $categorie, array(
'attr' => array('typeid' => $type->getId()),
));
$form->handleRequest($request);
Dans le formulaire
public function buildForm(FormBuilderInterface $builder, array $options)
{
$typeid = $options['attr']['typeid'];
var_dump($typeid);
$builder->add(...);
}
Trier les champs du formulaire dans l'ordre des Id depuis le formaulaire
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('menus', CollectionType::class, array(
'entry_type' => MenuType::class,
))
;
}
public function finishView(FormView $view, FormInterface $form, array $options)
{
usort($view['menus']->children, function (FormView $a, FormView $b) {
$objectA = $a->vars['data'];
$objectB = $b->vars['data'];
$posA = $objectA->getId();
$posB = $objectB->getId();
if ($posA == $posB) {
return 0;
}
return ($posA < $posB) ? -1 : 1;
});
}
Query_builder avec une variable pour un EntityType
L'EntityType du fomulaire va afficher tous les chapitres du même livre et non tous les chapitres existants en base de données
Télécharger le pack minimumHéritage des formulaires
Télécharger le pack minimumCacher un champ texte
use Symfony\Bridge\Doctrine\Form\Type\HiddenType;
$builder->add('name', HiddenType::class);
Cacher un champ date
$builder->add('startdate', null, array(
'label' => false,
'attr' => array('style'=>'display:none;')
));
Cacher un champ file
$builder->add('file', null, array(
'label' => false,
'attr' => array('style'=>'display:none;')
));
Cacher un champ entity
$builder->add('workshops', EntityType::class, array(
'class' => 'SofictifStretchingBundle:Workshop',
'label' => false,
'choice_label' => false,
'multiple' => true,
'attr' => array('style'=>'display:none;'),
));
Désactiver les validations de l'entitié (Assert) dans un formulaire (erreur "The file could not be found.")
use Symfony\Component\OptionsResolver\OptionsResolver;
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => false,
));
}
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="enregistrer" />
{{ form_end(edit_form) }}
{{ form_start(edit_form) }}
<div>
{{ form_label(edit_form.name) }}
{{ form_errors(edit_form.name) }}
{{ form_widget(edit_form.name) }}
</div>
<input type="submit" value="enregistrer" />
{{ form_end(edit_form) }}
{{ form_start(edit_form) }}
<div>
{{ form_label(edit_form.name, 'Nouveau label') }}
{{ form_errors(edit_form.name) }}
{{ form_widget(edit_form.name) }}
</div>
<input type="submit" value="enregistrer" />
{{ form_end(edit_form) }}
{{ form_start(edit_form) }}
<div style="display:none;">
{{ form_row(edit_form.title) }}
</div>
{{ form_end(edit_form) }}
{{ form_start(edit_form) }}
<div>
{{ form_label(edit_form.themes, null, {'label_attr': {'class':'hidden'}}) }}
{{ form_errors(edit_form.themes) }}
{{ form_widget(edit_form.themes) }}
</div>
{{ form_end(edit_form) }}
php composer.phar update jasig/phpcas
php composer.phar update
Dans app > config > config.yml :
parameters:
images_directory: '%kernel.root_dir%/../web/uploads/images'
Créer un dossier "uploads" vide dans web
Dans src > Sofictif > StretchingBundle > Entity > Position.php
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Column(type="string", length=255, nullable=true)
* @Assert\File(
* maxSize = "10M",
* maxSizeMessage = "Ce fichier est trop lourd, le maximum est : 10 Mo",
* mimeTypes = {"image/png", "image/gif", "image/jpg", "image/jpeg"},
* mimeTypesMessage = "Choisissez un nouveau fichier : seuls les png, gif et jpg sont possibles"
* uploadIniSizeErrorMessage = "Choisissez un nouveau fichier : le fichier que vous avez chargé est trop lourd, le maximum pour le serveur est de 500 Mo",
* )
*/
private $image;
Dans src > Sofictif > StretchingBundle > Form > PositionType.php
use Symfony\Component\Form\Extension\Core\Type\FileType;
$builder->add('file', FileType::class, array(
'required' => false,
'label' => 'Fichier de l\'image',
'data_class' => null
));
Dans src > Sofictif > StretchingBundle > Controller > PositionController.php
Enregistrer le sercice
Dans src > Sofictif > StretchingBundle > Resources > config > service.yml
services:
sofictif_stretching.title:
class: Sofictif\StretchingBundle\Service\Title
Dans src > Sofictif > StretchingBundle > Service > Title.php
namespace Sofictif\StretchingBundle\Service;
class Title
{
/**
* Supprimer les éléments inutiles d'une chaine de caractère
*
* @param string $text
* @return string
*/
public function cleanTitle($text)
{
// Supprimer les espaces en début et fin de chaîne
$text = trim($text);
// Remplacer les espaces multiples en milieu de chaîne par un espace unique
$text = preg_replace('/ +/', ' ', $text);
// Supprimer les tirets en début et fin de chaîne
$text = trim($text, '-');
return $text;
}
}
Dans src > Sofictif > StretchingBundle > Controller > BookController.php
$servicetitle = $this->get('sofictif_stretching.title');
$title = $servicetitle->cleanTitle('titre');
Enregistrer le sercice
Dans src > Sofictif > StretchingBundle > Resources > config > service.yml
services:
sofictif_stretching.calcul:
class: Sofictif\StretchingBundle\Service\Calcul
tags:
- { name: twig.extension }
Dans src > Sofictif > StretchingBundle > Service > Calcul.php
namespace Sofictif\StretchingBundle\Service;
/**
* Description de Calcul
*
*/
class Calcul extends \Twig_Extension
{
public function getName()
{
return 'calculsofictif_extension';
}
public function getFunctions(){
return array(
new \Twig_SimpleFunction('multiplierpartrois', array($this, 'multiplier')),
);
}
public function multiplier($number){
$number = $number * 3;
return $number;
}
}
Dans src > Sofictif > StretchingBundle > Resources > views > base.html.twig
{{ multiplierpartrois(4) }}
Enregistrer l'extension Twig comme un sercice
Dans src > Sofictif > StretchingBundle > Resources > config > service.yml
services:
sofictif_stretching.query:
class: Sofictif\StretchingBundle\Service\Query
tags:
- { name: twig.extension }
arguments:
doctrine: "@doctrine"
Dans src > Sofictif > StretchingBundle > Service > Query.php
namespace Sofictif\StretchingBundle\Service;
class Query extends \Twig_Extension
{
protected $doctrine;
public function __construct($doctrine)
{
$this->doctrine = $doctrine;
}
public function getName()
{
return 'querysofictif_extension';
}
public function getFunctions(){
return array(
new \Twig_SimpleFunction('listofbookswithtwig', array($this, 'retrieveallthebooks')),
new \Twig_SimpleFunction('retrieveabookwithtwig', array($this, 'retrieveabook')),
);
}
public function retrieveallthebooks(){
$em = $this->doctrine->getManager();
$books = $em->getRepository('SofictifStretchingBundle:Book')->findAll();
return $books;
}
public function retrieveabook($id){
$em = $this->doctrine->getManager();
$book = $em->getRepository('SofictifStretchingBundle:Book')->find($id);
return $book;
}
}
Utilisation dans Twig
Récupération de la liste complète
{% for book in listofbookswithtwig() %}
{{book.title}}
{% endfor %}
Récupération d'un élément
{{ retrieveabookwithtwig(3).title }}
{% extends 'SofictifStrecthingBundle::base.html.twig' %}
{% if position.description is defined %}
{{ position.description }}
{% else %}
Pas de position trouvée
{% endif %}
{% if position.description is defined %}
{{ position.description }}
{% endif %}
{% for position in positions %}
{{ position.name }}{% if loop.last == false %}, {% endif %}
{% else %}
Pas de position trouvée
{% endfor %}
{{ position.member.name }}
<a href="{{ path('position_new') }}">ajouter une nouvelle position</a>
<a href="{{ path('position_show', { 'id': position.id }) }}">{{ position.name }}</a>
{% include 'SofictifStretchingBundle::position/content.html.twig' %}
Définir des variables
{% set variablesgenerales = {
'titre': 'Stretching',
'description': 'Catalogue d'exercices'
} %}
Utiliser dans la même page
{{variablesgenerales.titre}}
Inclure une autre page avec ces variables
{% include 'CanopeEdelegueBundle::include/header.html.twig' with variablesgenerales %}
Utiliser ces variables dans la page inclue
{{titre}}
Page qui inclue une autre
{% include 'SofictifStretchingBundle::position/content.html.twig' with {'holder': true} %}
Page à inclure
{% if holder is not defined %}
{{ position.holder.name }}
{% endif %}
{% if position.acquired %}Oui{% else %}Non{% endif %}
<img src="{{ asset('images/canope.png') }}" alt="" title="" />
Dans un simple attribut
<a href="http://maps.google.com/?q= ~ {{ editor.address }} ~) }}">{{ editor.address }}</a>
<div style="background-color:{{ module.color }};"></div>
<img src="{{ asset('images/' ~ module.image ~ '') }}">
<video id="" controls poster="{{ asset('uploads/teaser/' ~ labtwig(1).poster) }}">
<source src="{{ asset('uploads/teaser/' ~ labtwig(1).teaser) }}" type="video/mp4">
Votre navigateur ne supporte pas la balise vidéo
</video>
Dans un attribut avec une valeur contenant un asset
<link rel="stylesheet" href="{{ asset('bundles/canopepreac/css/styles-' ~ categoriechoisie.slug ~ '.css') }}" />
Paramètres de l'application : dans app/config/config.yml
parameters:
$nbsp;$nbsp;$nbsp;$nbsp;app.version: 0.1.0
Configuration de Twig : dans app/config/config.yml
twig:
$nbsp;$nbsp;$nbsp;$nbsp;globals:
$nbsp;$nbsp;$nbsp;$nbsp;$nbsp;$nbsp;$nbsp;$nbsp;version: '%app.version%'
Dans le template Twig
{{ version }}
http://alexandre.clain.info/twig-les-variables-globales/
Récupérer l'url courante
{{ app.request.schemeAndHttpHost }}
{{ app.request.requestUri }}
{{ app.request.schemeAndHttpHost ~ app.request.requestUri }}
Récupérer l'hôte avec http
{{ app.request.schemeAndHttpHost }}
Récupérer le nom du serveur hôte qui exécute le script
{{ app.request.server.get("SERVER_NAME") }}
Récupérer l’url de base de l’application
{{ app.request.baseUrl }}
Récupérer le chemin de base
{{ app.request.basepath }}
Récupérer le chemin de la page courante sans le nom de domaine
{{ app.request.requestUri }}
Récupérer le chemin d’accès de l’application sans le nom de domaine
{{ app.request.pathInfo }}
Récupérer les méthodes de requêtes qui ont été utilisés à l’appel de la page (POST, GET)
{{ app.request.method }}
Récupérer l’environnement actuel (production, développement)
{{ app.environment }}
Savoir si le mode debug est activé ou non (retourne un boolean)
{{ app.debug }}
Récupérer les informations de l’utilisateur courant (entité User)
{{ app.user }}
Retourner la requête HTTP complète
{{ app.request }}
Récupérer le nom de la route utilisée
{{ app.request.attributes.get("_route") }}
Accéder à un paramètre d’une requête GET
{{ app.request.query.get("nom_du_parametre") }}
Accéder à un paramètre d’une requête POST
{{ app.request.parameter.get("nom_du_parametre") }}
Retourner une séquence des éléments téléchargé par le serveur lors d’un envoi de fichier(s)
{{ dump(app.request.files) }}
Accéder à un paramètre contenu dans un cookie
{{ app.request.cookies.get("nom_du_parametre") }}
Retourner toutes les informations du header de la requête HTTP (dont le user-agent, le referer, etc.)
{{ app.request.headers }}
Retourner toutes les informations du contenu de la requête HTTP
{{ app.request.content }}
Récupérer la séquence des langages acceptés par le navigateur
{{ dump(app.request.languages) }}
Récupérer la séquence des jeux de caractères acceptés par le navigateur
{{ dump(app.request.charsets) }}
Récupérer la séquence des types de contenus acceptés par le navigateur
{{ dump(app.request.acceptableContentTypes) }}
Récupérer la séquence listant toute les informations relative à la sécurité de la page de l’applicatio
{{ dump(app.security) }}
Récupérer des informations précises relatives à la sécurité
{{ app.security.token }}
{{ app.security.key }}
{{ app.security.user }}
{{ app.security.roles }}
{{ app.security.authenticated }}
{{ app.security.attributes }}
{{ app.security.alwaysAuthenticate }}
Afficher une session
{{ dump(app.request.session) }}
Accéder à un paramètre contenu dans une session
{{ app.request.session.get("nom_du_parametre") }}
http://alexandre.clain.info/twig-les-filtres-disponibles/#twig_title
https://packagist.org/packages/jasig/phpcas
https://wiki.jasig.org/display/CASC/Symfony+CAS+Client
Ce fichier au premier niveau de l'application répertorie la liste des bibliothèques dont le projet dépend.
Préciser dans "require" la version de la librairie externe :
"require": {
"jasig/phpcas": "^1.3",
},
php composer.phar require jasig/phpcas
Ajouter dans app/AppKernel.php :
$bundles = [
new Stfalcon\Bundle\TinymceBundle\StfalconTinymceBundle(),
];
Composer a donné à Symfony les informations de namespaces pour l'autoload
Rendre disponibles les nouveaux fichiers JS et CSS du bundle
Charger les fichiers CSS, copier les fichiers statiques des bundles dans web (utiliser --symlink pour des liens symboliques à la place de copies)
php bin/console assets:install
php composer.phar update jasig/phpcas
http://ckeditor.com/
https://packagist.org/packages/egeloen/ckeditor-bundle
http://symfony.com/doc/current/bundles/IvoryCKEditorBundle/index.html
Déclarer la dépendance dans le fichier composer.json
Il répertorie la liste des bibliothèques dont le projet dépend)
Préciser dans "require" sa version :
"require": {
"egeloen/ckeditor-bundle": "~4.0"
},
Installer le dossier de cette bibliothèques et ceux de ses dépendancesdans le dossier "vendor" :
php composer.phar require egeloen/ckeditor-bundle
Enregistrer le bundle dans le Kernel (permet à Composer de donner à Symfony les informations de namespaces pour l'autoload en ajoutant dans AppKernel.php :
$bundles = [
new Ivory\CKEditorBundle\IvoryCKEditorBundle(),
];
Installer les fichiers JS et CSS du bundle
Utiliser --symlink pour des liens symboliques à la place de copies
Il se crée dans web/bundles un dossier "ivoryckeditor" dans lesquels sont copiés les fichiers statiques.
php bin/console assets:install web
Mettre à jour uniquement de cette bibliothèque
php composer.phar update egeloen/ckeditor-bundle
Dans app/config/config.yml :
ivory_ck_editor:
default_config: my_config
configs:
my_config:
toolbar: "my_toolbar"
language: fr
skin: '../../../ckeditor/skins/moono-dark'
toolbars:
configs:
my_toolbar: [ "@my_clipboard","@my_editing","@my_document","@my_tools","/","@my_paragraph","@my_styles","@my_basicstyles","@my_links","@my_insert" ]
items:
my_clipboard: [ 'Cut','Copy','PasteText' ]
my_editing: [ 'Find','-','Scayt' ]
my_document: [ 'Undo','Redo','-','Preview','Source','-','Print' ]
my_tools: [ 'ShowBlocks','-','About' ]
my_paragraph: [ 'JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','NumberedList','BulletedList','-','Blockquote' ]
my_styles: [ 'Format' ]
my_basicstyles: [ 'Bold','Italic','Underline','Subscript','Superscript','-','RemoveFormat' ]
my_links: [ 'Link','Unlink','Anchor' ]
my_insert: [ 'Image','Table','HorizontalRule','PageBreak','SpecialChar' ]
Dans src > Sofictif > StretchingBundle > Form > PositionType.php :
use Ivory\CKEditorBundle\Form\Type\CKEditorType;
$builder->add('description', CKEditorType::class, array(
'required' => false,
'label' => ' ',
'config_name' => 'my_config',
));
Correspondance dans l'entité src > Sofictif > StretchingBundle > Entity > Position.php :
/**
* @ORM\Column(name="content", type="text", nullable=true)
*/
private $content;
Télécharger d'autres skins ici :
http://ckeditor.com/addons/skins/all
http://www.malot.fr/bootstrap-datetimepicker/
https://bootstrap-datepicker.readthedocs.io/
<script src="{{ asset('bootstrap-3.3.7-dist/js/bootstrap.js') }}"></script>
<script src="{{ asset('bootstrap-datetimepicker-master/js/bootstrap-datetimepicker.min.js') }}"></script>
<script src="{{ asset('bootstrap-datetimepicker-master/js/locales/bootstrap-datetimepicker.fr.js') }}"></script>
<script src="{{ asset('js/jquery-datepicker-addicons.js') }}"></script>
<script type="text/javascript">
(function($) {
$(document).ready(function(){
$(".datepickeryearmonthday").datetimepicker({
pickerPosition: "bottom-right",
language: 'fr',
weekStart: 1, // commencer avec le lundi
// daysOfWeekDisabled: '0,6', // rendre insélectionnable les samedi et dimanche
startView: 3, // démarrer avec la vue d'une année avec ses mois
format: 'yyyy-mm-dd',
minView: 2,
autoclose: true,
});
$(".datestimepicker").addicons();
});
})(jQuery);
</script>
<link href="{{ asset('bootstrap-3.3.7-dist/css/bootstrap.css') }}" rel="stylesheet" />
<link href="{{ asset('bootstrap-datetimepicker-master/css/bootstrap-datetimepicker.css') }}" rel="stylesheet" />
Correspondance dans l'entité src > Sofictif > StretchingBundle > Entity > Position.php :
/**
* @ORM\Column(name="datestart", type="date", nullable=true)
*/
private $datestart;
Dans src > Sofictif > StretchingBundle > Form > PositionType.php :
use Symfony\Component\Form\Extension\Core\Type\DateType;
$builder->add('datestart', DateType::class, array(
'required' => false,
'label' => 'Début de l\'événement',
'attr' => array('class' => 'datepickeryearmonthday'),
'widget' => 'single_text',
'format' => 'yyyy-MM-dd',
));
Pour utiliser la console sur un hébergement mutualisé qui n'offre pas d'accès SSH pour utiliser, installer CoreSphereConsoleBundle qui permet d'utiliser les commandes depuis le navigateur.
https://packagist.org/packages/coresphere/console-bundle
https://github.com/CoreSphere/ConsoleBundle
Ce fichier au premier niveau de l'application répertorie la liste des bibliothèques dont le projet dépend.
Préciser dans "require" la version de la librairie externe :
"require": {
"coresphere/console-bundle": "~0.4",
},
php composer.phar require coresphere/console-bundle
Ajouter dans app/AppKernel.php :
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
...
$bundles[] = new CoreSphere\ConsoleBundle\CoreSphereConsoleBundle();
}
Composer a donné à Symfony les informations de namespaces pour l'autoload
Dans le fichier app/config/routing_dev.yml (pas dans routing.yml, car la console ne doit être accessible qu'en mode dev).
coresphere_console:
resource: .
type: extra
Rendre disponibles les nouveaux fichiers JS et CSS du bundle
Charger les fichiers CSS, copier les fichiers statiques des bundles dans web (utiliser --symlink pour des liens symboliques à la place de copies)
php bin/console assets:install
php composer.phar update coresphere/console-bundle
Ne pas mettre "php bin/console"
http://localhost/site_stretching/web/app_dev.php/_console
cache:clear
cache:clear --env=prod
doctrine:schema:update --dump-sql
doctrine:schema:update --force
Placer un fichier .htaccess à la racine du site dans lequel il y a :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ web/$1 [QSA,L]
</IfModule>
Ne fonctionne pas en local mais sur serveur, une fois les caches bien vidés.
Dans le fichier app/config/parameters.yml, adapter les valeurs des paramètres "database_name", "database_user" et "database_password" pour pouvoir accéder au phpMyAdmin du serveur.
Solution 1 : exporter la base de données depuis http://localhost/phpmyadmin/ dans un fichier avec un format .sql
Puis importer ce même fichier dans le phpMyAdmin du serveur (dans lequel on a préalablement créé une base de données du même nom vide)
Solution 2 : créer la base de données renseignée dans le fichier parameters.yml, en exécutant la commande :
php bin/console doctrine:database:create
Puis la remplir avec les tables correspondant aux entités :
php bin/console doctrine:schema:update --force
Envoyer un fichier phpinfo.php (contenant la fonction phpinfo(); pour vérifier que JSON, Ctype, Sqlite3, PDO et le mode rewrite sont bien activés, que le Php.ini a bien le paramètre date.timezone défini à Europe/Paris
php composer.phar self-update
php composer.phar update
php composer.phar install --optimize-autoloader
L'option --optimize-autoloader rend l'autoloader de Composer plus performant en construisant une map
Solution 1
Envoyer manuellement le fichier "composer.lock" sur l'interface en ligne security.sensiolabs.org
composer.lock contient tous les numéros des versions des dépendances que j'ai installées en local
Si le message suivant s'affiche : "Great! etc.", les dépendances ne contiennent pas de faille de sécurité : on peut continuer.
Solution 2
php bin/console security:check
Si le message "No packages have know vulnerabilities" apparaît, on peut continuer.
Si une dépendance a une faille connue, la plupart du temps, mettre à jour la bibliothèque dans une version plus récente résoudra le problème.
Installer les ressources dans le dossier web
Rendre disponibles les nouveaux fichiers JS et CSS du bundle
Charger les fichiers CSS, copier les fichiers statiques des bundles dans web (utiliser --symlink pour des liens symboliques à la place de copies)
php bin/console assets:install
Activer le mode debugger pour la partie production : modifier le fichier web/app.php en définissant le deuxième argument de AppKernel à true :
$kernel = new AppKernel('prod', true);
Cela permet d'afficher les erreurs de cet environnement à l'écran.
Tester en utilisant le contrôleur frontal app.php (sans app_dev.php dans l'url) :
http://localhost/site_stretching/web/
Si tout est ok, remettre à false : les erreurs sont à nouveau répertoriées dans le fichier var/logs/prod. Ce sont elles qui'il faut consulter en cas de soucis sur le site en production.
Vider le cache de l'environnement de développement
php bin/console cache:clear
Vider le cache de l'environnement de production
php bin/console cache:clear --env=prod
Puis supprimer physiquement tout le contenu des dossiers du cache (la commandecache:clearne fait pas que supprimer le cache, elle le reconstruit en partie).
- La version de PHP doit être supérieure ou égale à PHP 5.5.9
- L'extension SQLite 3 doit être activée
- L'extension JSON doit être activée
- L'extension Ctype doit être activée
- Le paramètre date.timezone doit être défini dans le php.ini
Commenter les lignes du fichier web/config.php :
// if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
// '127.0.0.1',
// '::1',
// ))) {
// header('HTTP/1.0 403 Forbidden');
// exit('This script is only accessible from localhost.');
// }
L'envoyer sur le serveur par Ftp et allez voir :
http://www.crdp-lyon.fr/stretching/web/config.php
S'il n'y a pas de partie « Major Problems », le serveur est compatible avec Symfony, décommenter et renvoyer le fichier.
Il permet de booster les performances de l'application en production, obtenir des temps d'exécution plus rapides.
Il faut dé-commenter la ligne extension=Php_apc.dll dans le Php.ini et ajouter [APC] apc.enabled=1 à la fin de ce même fichier
Pour exécuter les commandes Symfony, notamment celles pour créer la base de données
http://www.crdp-lyon.fr/stretching/web/app_dev.php
Ce message apparaît : "You are not allowed to access this file. Check app_dev.php for more information."
Dans le fichier web/app_dev.php, ne pas supprimer la condition (car on aura besoin d'accéder à l'environnement de développement ultérieurement), mais compléter la condition avec notre adresse IP (www.whatismyip.com)
if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
'127.0.0.1',
'::1',
'193.49.39.141'
))) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
Envoyer à nouveau le fichier app_dev.php par Ftp et verifier :
http://www.crdp-lyon.fr/stretching/web/app_dev.php
Pour avoir http://stretching.crdp-lyon.fr/ au lieu de http://stretching.crdplyon.fr/web/
Utiliser un VirtualHost (domaine virtuel) pour indiquer à Apache de créer un raccourci
http://preac.crdplyon.fr/ pointe directement vers le répertoire preac/web
Possible avec un client FTP (Filezilla)
Les répertoires concernés sont var/cache, var/log, web/uploads
Vérifier que les deux fichiers composer.json et composer.lock sont bien présents au premier niveau sur le serveur
Installer les dépendances sur le serveur avec les mêmes versions que celles en local (composer.lock contient tous les numéros des versions installée)
php composer.phar install
1. Tout fonctionne correctement dans l'environnement de production
2. L'accès à l'environnement de développement sur le serveur est bien inaccessible à tous