Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2020-06-18T16:20:00+02:00Les derniers messages parus sur le forum de Zeste de Savoir.Traitement d'un input, message #2226292020-06-18T16:20:00+02:00viki53/@viki53https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222629<p>Et le <code>execute</code> renvoie bien <code>true</code> ?</p>
<p><a href="https://www.php.net/manual/fr/pdostatement.debugdumpparams.php"><code>$query->debugDumpParams()</code></a> donne quoi ?</p>Traitement d'un input, message #2226262020-06-18T16:10:21+02:00romain.revert92/@romain.revert92https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222626<p>Non du tout, le résultat est le même :/</p>Traitement d'un input, message #2226252020-06-18T16:03:41+02:00viki53/@viki53https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222625<p>Et si tu remplaces ta requête par <code>UPDATE {$this->table} SET items = :items WHERE users_id = :users_id</code> est-ce que ça change quelque chose ?</p>Traitement d'un input, message #2226232020-06-18T15:40:46+02:00romain.revert92/@romain.revert92https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222623<p>Oui, je m’en sers souvent pour mettre en place d’autres fonctionnalités, jusqu’à présent cela avait toujours fonctionné, je ne comprend pas pourquoi ici il refuse de m’indiquer quoique ce soit.</p>
<p>Elle renvoie les produits (que j’ai nommé items) que contient le panier de l’utilisateur.</p>
<p>En fait c’est pour plus de praticité, cela me permet de ne pas avoir à serialize / unserialize mon tableau à chaque fois, je conviens que ce n’est pas la méthode la plus propre cela dit.</p>Traitement d'un input, message #2226222020-06-18T15:33:26+02:00viki53/@viki53https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222622<p>As-tu activé le mode d’erreur qui lance des exceptions sur PDO ?</p>
<p>La fonction <code>$cart->getItems()</code> renvoie quoi ?</p>
<hr>
<p>Je trouve un peu bizarre d’avoir des <code>serialize/unserialize</code> à l’extérieur de la relation avec la BDD : ça devrait être dans les <code>class</code> qui communiquent avec ta base que tu devrais gérer ça de façon transparente.</p>Traitement d'un input, message #2226212020-06-18T15:27:05+02:00romain.revert92/@romain.revert92https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222621<p>Je traite le panier sous forme de tableau serializé qui contient l’id du produit, le nom et la quantité, cela m’évite d’avoir une nouvelle ligne dans la table par commande. Voici les requêtes que j’utilise :</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div><pre><code class="hljs language-sql">
public function getCart ($users_id)
{
$query = $this->pdo-><span class="hljs-keyword">prepare</span>(<span class="hljs-string">"SELECT items FROM {$this->table} WHERE users_id = :users_id"</span>);
$query-><span class="hljs-keyword">execute</span>([<span class="hljs-string">'users_id'</span> => $users_id]);
$query->setFetchMode(PDO::FETCH_CLASS, $this->class);
$cart = $query->fetch();
return $cart == false ? [] : unserialize($cart->getItems());
}
public function updateCart (Carts $cart)
{
$query = $this->pdo-><span class="hljs-keyword">prepare</span>(<span class="hljs-string">"UPDATE {$this->table} SET users_id = :users_id, items = :items"</span>);
$query-><span class="hljs-keyword">execute</span>([
<span class="hljs-string">'users_id'</span> => $cart->getUsers_Id(),
<span class="hljs-string">'items'</span> => $cart->getItems()
]);
}
</code></pre></div>
<p>Oui, j’ai essayé, j’ai mis des dump partout, mais je n’ai même pas de retour pour m’indiquer ce qui cloche …</p>Traitement d'un input, message #2226192020-06-18T15:22:15+02:00viki53/@viki53https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222619<p>Donc il faudrait voir ce qu’il se passe lors de la modification… elles ressemblent à quoi tes requêtes vers la BDD ?</p>
<p>As-tu tracé la fonction <code>updateItem</code> pour voir où passe ton script ?</p>Traitement d'un input, message #2226172020-06-18T15:14:51+02:00romain.revert92/@romain.revert92https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222617<p>La page se recharge et m’affiche les données d’avant la modification, rien ne se passe également dans la base de données, ou la quantité reste la même.</p>Traitement d'un input, message #2226162020-06-18T15:12:54+02:00viki53/@viki53https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222616<p>Hello <img src="/static/smileys/svg/smile.svg" alt=":)" class="smiley"> </p>
<p>Est-ce que tu récupères les données à nouveau entre la mise à jour et l’affichage ?</p>
<p>As-tu tracé les requêtes vers la BDD pour voir ce qu’il se passait ?</p>Traitement d'un input, message #2226152020-06-18T15:08:35+02:00romain.revert92/@romain.revert92https://zestedesavoir.com/forums/sujet/14243/traitement-dun-input/?page=1#p222615<p>Bonjour à tous,</p>
<p>Je viens vers vous car je rencontre un petit problème. Je souhaite que l’utilisateur puisse modifier la quantité d’un objet dans son panier s’il le souhaite, via un input tout simple fait avec bootstrap (cf capture d’écran). Je vous poste le code que je vais expliquer ensuite.</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div><pre><code class="hljs language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateItem</span><span class="hljs-params">()</span>
</span>{
$cartsTable = <span class="hljs-keyword">new</span> CartsTable();
$cart = $cartsTable->getCart(Auth::getUserId());
<span class="hljs-keyword">foreach</span> ($cart <span class="hljs-keyword">as</span> $key => $value) {
$_POST[<span class="hljs-string">'quantity'</span>] = $key;
<span class="hljs-keyword">if</span> ($_POST[<span class="hljs-string">'down'</span>] != $key || $_POST[<span class="hljs-string">'up'</span>] != $key) {
array_slice($cart, $_POST[<span class="hljs-string">'quantity'</span>]);
}
}
$cart = serialize($cart);
$carts = <span class="hljs-keyword">new</span> Carts();
$carts
->setUsers_Id(Auth::getUserId())
->setItems($cart);
$cartsTable->updateCart($carts);
}
</code></pre></div>
<p>Dans un premier temps, je récupère le panier de l’utilisateur que je déserialize pour ensuite mettre en place le changement de quantité via l’input. Si la valeur est différente, je met à jour le panier après la condition. Sauf qu’il ne se passe absolument rien lors du traitement, la page se recharge, mais la quantité reste la même, je n’ai pas de messages d’erreur, j’ai l’impression que tout le code n’est pas pris en compte. Je vous met ci-dessous le formulaire</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div><pre><code class="hljs language-html"> {% for item_id, item in cart %}
<span class="hljs-tag"><<span class="hljs-name">tr</span>></span>
<span class="hljs-tag"><<span class="hljs-name">td</span>></span>{{ product_name(item_id) }}<span class="hljs-tag"></<span class="hljs-name">td</span>></span>
<span class="hljs-tag"><<span class="hljs-name">td</span>></span>
{{ form.start() }}
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"def-number-input number-input safari_only"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"down"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"this.parentNode.querySelector('input[type=number]').stepDown()"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"fa fa-minus"</span>></span><span class="hljs-tag"></<span class="hljs-name">i</span>></span>
<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"quantity"</span> <span class="hljs-attr">min</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"quantity"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"{{ item.quantity }}"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"up"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"this.parentNode.querySelector('input[type=number]').stepUp()"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"fa fa-plus"</span>></span><span class="hljs-tag"></<span class="hljs-name">i</span>></span>
<span class="hljs-tag"></<span class="hljs-name">button</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
{{ form.end() }}
<span class="hljs-tag"></<span class="hljs-name">td</span>></span>
<span class="hljs-tag"><<span class="hljs-name">td</span>></span>
{{ form.start({action:generate('technicien_cart_item_delete')}) }}
{{ tag.input({type:'hidden', name:'product_id', value:item_id}) }}
<span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-danger"</span>></span><span class="hljs-tag"><<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"fas fa-trash"</span>></span><span class="hljs-tag"></<span class="hljs-name">i</span>></span><span class="hljs-tag"></<span class="hljs-name">button</span>></span>
{{ form.end() }}
<span class="hljs-tag"></<span class="hljs-name">td</span>></span>
<span class="hljs-tag"></<span class="hljs-name">tr</span>></span>
{% endfor %}
</code></pre></div>
<p>Je ne sais pas vraiment d’ou peut venir le problème, car la logique me paraissait bonne. Si quelqu’un peut jeter un oeil et me dire ou est-ce que cela cloche, je lui en serait très reconnaissant ! Merci d’avance <img src="/static/smileys/svg/smile.svg" alt=":)" class="smiley"></p>
<figure><img src="/media/galleries/11576/9ee5329f-bb07-489c-8405-784ae5311ad2.png" alt="image.png"><figcaption>image.png</figcaption></figure>Site multilingue php/twig, message #1523452017-06-04T16:33:29+02:00WinXaito/@WinXaitohttps://zestedesavoir.com/forums/sujet/8734/site-multilingue-phptwig/?page=1#p152345<p>Merci je ne l’avais pas remarqué <img alt=";)" src="/static/smileys/clin.png"></p>Site multilingue php/twig, message #1522252017-06-02T19:42:00+02:00anonyme/@anonymehttps://zestedesavoir.com/forums/sujet/8734/site-multilingue-phptwig/?page=1#p152225<p>Tu as regardé i18n ? <a href="http://symfony.com/doc/current/translation.html">C’est ce que Symfony utilise</a> et c’est assez poussé.</p>
<p><del>(Les Blundes de Symfony sont fait pour fonctionner séparément de Symfony donc tu pourras facilement l’ajouter à ton code en suivant les instructions du README).</del></p>
<p><strong>EDIT :</strong> C’est <a href="http://twig-extensions.readthedocs.io/en/latest/i18n.html">une extension Twig</a>.</p>Site multilingue php/twig, message #1522132017-06-02T16:43:18+02:00WinXaito/@WinXaitohttps://zestedesavoir.com/forums/sujet/8734/site-multilingue-phptwig/?page=1#p152213<p>Bonjour,</p>
<p>J’aurais aimé savoir qu’elle était la meilleure méthodes pour faire un site web multilingue en utilisant le gestionnaire de template Twig (sur php7).</p>
<p>Merci</p>Symfony 3 - FostRestBundle - Retourner 1 template twig, message #1394152017-01-24T09:21:45+01:00gusavy/@gusavyhttps://zestedesavoir.com/forums/sujet/7842/symfony-3-fostrestbundle-retourner-1-template-twig/?page=1#p139415<p>Merci ça marche super!:)</p>Symfony 3 - FostRestBundle - Retourner 1 template twig, message #1393812017-01-23T20:38:37+01:00BestCoder/@BestCoderhttps://zestedesavoir.com/forums/sujet/7842/symfony-3-fostrestbundle-retourner-1-template-twig/?page=1#p139381<p>tu peux créer une règle juste pour ton formulaire.</p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span> format_listener:
rules:
- { path: '^/url/qui/genere/formulaire', priorities: ['html'], fallback_format: 'html' }
- { path: '^/', priorities: ['json'], fallback_format: 'json' }
</pre></div>
</td></tr></table></div>
<p>FOSRestBundle pourra utiliser twig en interne pour générer ton formulaire.</p>
<p><a href="http://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html">http://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html</a></p>Symfony 3 - FostRestBundle - Retourner 1 template twig, message #1393622017-01-23T17:17:46+01:00gusavy/@gusavyhttps://zestedesavoir.com/forums/sujet/7842/symfony-3-fostrestbundle-retourner-1-template-twig/?page=1#p139362<p>C’est pour un système d’ecommerce. Notre appli est fractionné en 2. 1 partie front end fait avec dupral et une partie backend avec symfony3. Sur la partie front end (dupral) l’internaute configure son panier d’achat (nbre de produit acheté, options supplémentaire, etc) en appelant des webservice du backend (symfony). Et au moment de payer le système de paiement d’une banque demande 1 "formulaire html scellé" avec différentes informations calculé du côté backend affiché sur la partie frontend. Ensuite il ya une communication entre l’internaute et le serveur de la banque et ensuite entre le serveur de la banque et notre backend et enfin 1 retour sur la partie front end en fin de paiement. Voila pourquoi j’avais besoin de savoir si cétait possible ou pas.
J’espère m’être fait comprendre un minimum.</p>Symfony 3 - FostRestBundle - Retourner 1 template twig, message #1393492017-01-23T14:43:41+01:00BestCoder/@BestCoderhttps://zestedesavoir.com/forums/sujet/7842/symfony-3-fostrestbundle-retourner-1-template-twig/?page=1#p139349<p>Pourquoi veux-tu renvoyer un formulaire ? Dans quel contexte veux-tu utiliser un tel système ?</p>Symfony 3 - FostRestBundle - Retourner 1 template twig, message #1393452017-01-23T12:01:06+01:00gusavy/@gusavyhttps://zestedesavoir.com/forums/sujet/7842/symfony-3-fostrestbundle-retourner-1-template-twig/?page=1#p139345<p>Merci pour ta réponse rapide. J’ai pensé à cette solution mais en fait je doit envoyer simplement un formulaire et je suis obligé de passer par l’authentification par token. </p>Symfony 3 - FostRestBundle - Retourner 1 template twig, message #1393432017-01-23T11:16:08+01:00BestCoder/@BestCoderhttps://zestedesavoir.com/forums/sujet/7842/symfony-3-fostrestbundle-retourner-1-template-twig/?page=1#p139343<p>Salut,</p>
<p>Je cite une réponse que j’avais mise dans les commentaires du cours. Cela pourra t’aider dans ton problème.</p>
<figure>
<blockquote>
<p>Si tu veux que les pages html soient affichées par ton application, il faut changer les urls de ton api. Tu peux par exemple ajouter un préfixe /api dans toutes les routes de ton api, et configurer FOSREstBundle pour qu’il soit actif que sur ces routes.</p>
<p>La déclaration des routes pourrait ressembler à :</p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="x">places:</span>
<span class="x"> type: rest</span>
<span class="x"> resource: AppBundle\Controller\PlaceController</span>
<span class="x"> prefix: /api</span>
</pre></div>
</td></tr></table></div>
<p>La configuration de FOSRestBundle devra prendre en compte les nouvelles routes.</p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="x"># src/app/config/config.yml</span>
<span class="x">fos_rest:</span>
<span class="x"> routing_loader:</span>
<span class="x"> include_format: false</span>
<span class="x"> view:</span>
<span class="x"> view_response_listener: true</span>
<span class="x"> zone:</span>
<span class="x"> - { path: ^/api }</span>
<span class="x"> format_listener:</span>
<span class="x"> rules:</span>
<span class="x"> - { path: '^/api', priorities: ['json'], fallback_format: 'json' }</span>
</pre></div>
</td></tr></table></div>
<p>La partie zone permet d’activer le bundle que pour les routes commençants par api. IL ne faut pas aussi oublier de reconfigurer la partie sécurité pour qu’elle corresponde aux nouvelles urls.</p>
</blockquote>
<figcaption><a href="/tutoriels/1280/creez-une-api-rest-avec-symfony-3/?page=2#p132261">briceouabo</a></figcaption>
</figure>
<p>Cette technique permet d’isoler l’API dans le préfixe /api et tout le reste de ton application pourra fonctionner comme une application Symfony classique.</p>
<p>Cordialement.</p>Symfony 3 - FostRestBundle - Retourner 1 template twig, message #1393402017-01-23T10:30:07+01:00gusavy/@gusavyhttps://zestedesavoir.com/forums/sujet/7842/symfony-3-fostrestbundle-retourner-1-template-twig/?page=1#p139340<p>Bonjour,</p>
<p>J’ai suivi le tuto "Créer une API Rest avec Symfony et FostRestBundle".
J’ai créer ma propre api qui retourne des données JSON avec succès.
Maintenant j’ai un besoin de retourner 1 template twig.
Savez vous comment faire ?</p>Comportement différent selon l'environnement, message #767172015-10-07T13:21:12+02:00Ymox/@Ymoxhttps://zestedesavoir.com/forums/sujet/4214/comportement-different-selon-lenvironnement/?page=1#p76717<p>Bonjour à tous !</p>
<p>J’ai un comportement que je n’arrive pas à cerner, et qui me paraît presque être un vrai bug de Symfony que de l’<abbr title="Interface Chaise-Clavier">ICC</abbr>.</p>
<p>J’ai un formulaire avec un champ de type <code>choice</code>, dont je rends chaque option séparément en utilisant <code>form_widget(form.choiceField.0)</code>, <code>form_widget(form.choiceField.1)</code>, etc.<br>
Entre les options ainsi rendues, j’ai d’autres champs qui viennent. Le code est ci-dessous. L’idée étant de choisir un type de média et de renseigner le ou les champ(s) relatifs à ce type.</p>
<p>Maintenant, il se trouve que si les options de mon choiceField sont forcément requises, il n’en est pas de même pour les champs "intercalaires". Avec l’environnement de dev, pas de problème. Mais avec l’environnement de production, ces champs intercalaires, même s’ils sont bien spécifiés comme non requis dans le FormType, l’attribut <code>required</code> est ajouté. Du coup, on doit renseigner les informations pour tous les types de média alors qu’on n’enregistrera que les données d’un seul.</p>
<p>Il paraît que c’est quelque chose de connu, mais je n’ai pas réussi à en trouver trace sur le repository officiel, et n’ai pas de solution pour l’instant.<br>
Est-ce que quelqu’un aurait déjà observé un tel comportement et aurait un <em>workaround</em> à me proposer ?</p>
<div class="custom-block custom-block-information"><div class="custom-block-body"><p>Je précise que je parle des environnements Symfony. Ce souci a été constaté sur trois machines différentes en comparant le code HTML généré en passant par app.php et app_dev.php sur la même machine, tous caches purgés.</p></div></div>
<p>Merci d’avance</p>
<div class="custom-block custom-block-spoiler"><div class="custom-block-body"><figure><div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div><pre><code class="hljs language-php"><span class="hljs-meta"><?php</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">MyWonderfulBundle</span>\<span class="hljs-title">Entity</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Doctrine</span>\<span class="hljs-title">ORM</span>\<span class="hljs-title">Mapping</span> <span class="hljs-title">as</span> <span class="hljs-title">ORM</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">Validator</span>\<span class="hljs-title">Constraints</span> <span class="hljs-title">as</span> <span class="hljs-title">Assert</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">HttpFoundation</span>\<span class="hljs-title">File</span>\<span class="hljs-title">UploadedFile</span>;
<span class="hljs-comment">/**
* Media
* <span class="hljs-doctag">@ORM</span>\HasLifecycleCallbacks
* <span class="hljs-doctag">@ORM</span>\Table(name="media")
* <span class="hljs-doctag">@ORM</span>\Entity
*/</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Media</span>
</span>{
<span class="hljs-keyword">const</span> UPLOAD_DIR = <span class="hljs-string">'uploads/medias'</span>;
<span class="hljs-keyword">const</span> VIDEO = <span class="hljs-string">'video'</span>;
<span class="hljs-keyword">const</span> IMAGE = <span class="hljs-string">'image'</span>;
<span class="hljs-keyword">const</span> YOUTUBE_EMBED_BASE = <span class="hljs-string">'//www.youtube.com/embed/'</span>;
<span class="hljs-keyword">const</span> VIMEO_EMBED_BASE = <span class="hljs-string">'//player.vimeo.com/video/'</span>;
<span class="hljs-comment">/**
* <span class="hljs-doctag">@var</span> integer
*
* <span class="hljs-doctag">@ORM</span>\Column(name="id", type="integer", nullable=false)
* <span class="hljs-doctag">@ORM</span>\Id
* <span class="hljs-doctag">@ORM</span>\GeneratedValue(strategy="IDENTITY")
*/</span>
<span class="hljs-keyword">private</span> $id;
<span class="hljs-comment">/**
* <span class="hljs-doctag">@var</span> string
*
* <span class="hljs-doctag">@ORM</span>\Column(name="type", type="string", length=255, nullable=false)
*/</span>
<span class="hljs-keyword">private</span> $type;
<span class="hljs-comment">/**
* The name of the media.
* It can be the name of the image or the identifier of the video
*
* <span class="hljs-doctag">@var</span> string
*
* <span class="hljs-doctag">@ORM</span>\Column(name="name", type="string", length=255, nullable=true)
*/</span>
<span class="hljs-keyword">private</span> $name;
<span class="hljs-comment">/**
* The path of the media.
* This can be the base URL for a distant media, mostly the base embed URL
* for videos
*
* <span class="hljs-doctag">@var</span> string
*
* <span class="hljs-doctag">@ORM</span>\Column(name="path", type="string", length=255, nullable=true)
*/</span>
<span class="hljs-keyword">private</span> $path;
<span class="hljs-comment">/**
* <span class="hljs-doctag">@var</span> \DateTime
*
* <span class="hljs-doctag">@ORM</span>\Column(name="updatedAt", type="datetime", nullable=true)
*/</span>
<span class="hljs-keyword">private</span> $updatedAt;
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__toString</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>->getName();
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getTypeMedia</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">array</span>(<span class="hljs-keyword">self</span>::IMAGE => <span class="hljs-keyword">self</span>::IMAGE, <span class="hljs-keyword">self</span>::VIDEO => <span class="hljs-keyword">self</span>::VIDEO);
}
<span class="hljs-comment">/**
* Get id
*
* <span class="hljs-doctag">@return</span> integer
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getId</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>->id;
}
<span class="hljs-comment">/**
* Set type
*
* <span class="hljs-doctag">@param</span> string $type
* <span class="hljs-doctag">@return</span> Media
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setType</span><span class="hljs-params">($type)</span>
</span>{
<span class="hljs-keyword">$this</span>->type = $type;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>;
}
<span class="hljs-comment">/**
* Get type
*
* <span class="hljs-doctag">@return</span> string
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getType</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>->type;
}
<span class="hljs-comment">/**
* Set path
*
* <span class="hljs-doctag">@param</span> string $path
* <span class="hljs-doctag">@return</span> Media
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setPath</span><span class="hljs-params">($path)</span>
</span>{
<span class="hljs-keyword">$this</span>->path = $path;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>;
}
<span class="hljs-comment">/**
* Get path
*
* <span class="hljs-doctag">@return</span> string
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getPath</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>->path;
}
<span class="hljs-comment">/**
* Set name
*
* <span class="hljs-doctag">@param</span> string $name
* <span class="hljs-doctag">@return</span> Media
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setName</span><span class="hljs-params">($name)</span>
</span>{
<span class="hljs-keyword">$this</span>->name = $name;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>;
}
<span class="hljs-comment">/**
* Get name
*
* <span class="hljs-doctag">@return</span> string
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getName</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>->name;
}
<span class="hljs-comment">/**
* Set updatedAt
*
* <span class="hljs-doctag">@param</span> string $updatedAt
* <span class="hljs-doctag">@return</span> Media
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setUpdatedAt</span><span class="hljs-params">($updatedAt)</span>
</span>{
<span class="hljs-keyword">$this</span>->updatedAt = $updatedAt;
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>;
}
<span class="hljs-comment">/**
* Get updatedAt
*
* <span class="hljs-doctag">@return</span> string
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getUpdatedAt</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">$this</span>->updatedAt;
}
<span class="hljs-comment">/*************************************************************/</span>
<span class="hljs-comment">/**
* <span class="hljs-doctag">@Assert</span>\Image(
* minWidth = 600,
* minWidthMessage="L'image doit avoir une largeur minimale de 660 pixels",
* minHeight = 400,
* minHeightMessage="L'image doit avoir une hauteur minimale de 412 pixels",
* )
*/</span>
<span class="hljs-keyword">public</span> $file;
<span class="hljs-comment">// Getters et setters comme à l'accoutumée</span>
}
</code></pre></div><figcaption>Mon entité Media</figcaption></figure><figure><div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div><pre><code class="hljs language-php"><span class="hljs-meta"><?php</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">MyWonderfulBundle</span>\<span class="hljs-title">Form</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">Form</span>\<span class="hljs-title">AbstractType</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">Form</span>\<span class="hljs-title">FormBuilderInterface</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">OptionsResolver</span>\<span class="hljs-title">OptionsResolver</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">Form</span>\<span class="hljs-title">FormEvent</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">Form</span>\<span class="hljs-title">FormEvents</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">MyWonderfulBundle</span>\<span class="hljs-title">Entity</span>\<span class="hljs-title">Media</span>;
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MediaType</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractType</span>
</span>{
<span class="hljs-comment">/**
* <span class="hljs-doctag">@param</span> FormBuilderInterface $builder
* <span class="hljs-doctag">@param</span> array $options
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">buildForm</span><span class="hljs-params">(FormBuilderInterface $builder, array $options)</span>
</span>{
$builder
->add(<span class="hljs-string">'type'</span>, <span class="hljs-string">'choice'</span>, <span class="hljs-keyword">array</span>(
<span class="hljs-string">'choices'</span> => Media::getTypeMedia(),
<span class="hljs-string">'expanded'</span> => <span class="hljs-keyword">true</span>,
<span class="hljs-string">'multiple'</span> => <span class="hljs-keyword">false</span>,
<span class="hljs-string">'attr'</span> => <span class="hljs-keyword">array</span>(
<span class="hljs-string">'class'</span> => <span class="hljs-string">'radio'</span>
)
))
->add(<span class="hljs-string">'video_url'</span>, <span class="hljs-string">'text'</span>, <span class="hljs-keyword">array</span>(
<span class="hljs-string">'required'</span> => <span class="hljs-keyword">false</span>,
))
->add(<span class="hljs-string">'file'</span>, <span class="hljs-string">'file'</span>, <span class="hljs-keyword">array</span>(
<span class="hljs-string">'required'</span> => <span class="hljs-keyword">false</span>,
<span class="hljs-string">'label'</span> => <span class="hljs-string">'Image'</span>,
<span class="hljs-string">'attr'</span> => <span class="hljs-keyword">array</span>(
<span class="hljs-string">'accept'</span> => <span class="hljs-string">'image/*'</span>,
<span class="hljs-string">'class'</span> => <span class="hljs-string">'filestyle'</span>
)
))
->add(<span class="hljs-string">'name'</span>, <span class="hljs-string">'hidden'</span>)
->add(<span class="hljs-string">'path'</span>, <span class="hljs-string">'hidden'</span>)
->add(<span class="hljs-string">'updatedAt'</span>, <span class="hljs-string">'datetime'</span>, <span class="hljs-keyword">array</span>(
<span class="hljs-string">'data'</span> => <span class="hljs-keyword">new</span> \DateTime(),
<span class="hljs-string">'attr'</span> => <span class="hljs-keyword">array</span>(<span class="hljs-string">'class'</span> => <span class="hljs-string">'hidden'</span>),
<span class="hljs-string">'label'</span> => <span class="hljs-keyword">false</span>
))
;
}
<span class="hljs-comment">/**
* <span class="hljs-doctag">@param</span> OptionsResolver $resolver
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">configureOptions</span><span class="hljs-params">(OptionsResolver $resolver)</span>
</span>{
$resolver->setDefaults(<span class="hljs-keyword">array</span>(
<span class="hljs-string">'data_class'</span> => <span class="hljs-string">'MyWonderfulBundle\Entity\Media'</span>
));
}
<span class="hljs-comment">/**
* <span class="hljs-doctag">@return</span> string
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getName</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">return</span> <span class="hljs-string">'my_wonderful_bundle_media'</span>;
}
}
</code></pre></div><figcaption>Le FormType associé</figcaption></figure><figure><div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div><pre><code class="hljs language-html+django"><div class="well">
{% if form.vars.value is not empty -%}
{% if form.type.vars.value == constant('MyWonderfulBundle\\Entity\\Media::IMAGE') -%}
{{ form.vars.value|media({'class':'img-thumbnail ' ~ form.parent.vars.name|slice(0, -1)}) }}
{% elseif form.type.vars.value == constant('MyWonderfulBundle\\Entity\\Media::VIDEO') -%}
{{ form.vars.value|media({'width':'150','height':'150'}) }}
{%- endif %}
{%- endif %}
<div class="form-group clearfix">
{{ form_widget(form.type.0, (displayVideo ? {} : {'attr': {'checked': true}, 'label_attr': {'class': 'hidden'}})) }}
</div>
<div class="form-group clearfix">
{{ form_widget(form.file) }}
</div>
{% if displayVideo %}
<div class="form-group clearfix">
{{ form_widget(form.type.1) }}
</div>
<div class="form-group clearfix">
{{ form_widget(form.video_url) }}
</div>
{% endif %}
{{ form_widget(form.name) }}
{{ form_widget(form.updatedAt) }}
</div>
</code></pre></div><figcaption>Le template pour le formulaire de l’entité</figcaption></figure></div></div>
<h4 id="edit-9-octobre-2015">Edit 9 octobre 2015<a aria-hidden="true" href="#edit-9-octobre-2015"><span class="icon icon-link"></span></a></h4>
<p>Il n’est pas impossible que ce soit dû à l’utilisation d’une macro plutôt que le système de templating. La piste me vient de <a href="https://github.com/symfony/symfony/issues/15544" title="[Bug] [Form] 2.7 - Form collection prototype required option">cette discussion</a>, plus précisement <a href="https://github.com/symfony/symfony/issues/15544#issuecomment-130710735">la réponse de stof</a> qui précise un souci avec la gestion de <code>required</code> du fait des macros existantes.</p>
<h4 id="edit-9-octobre-2015-2">Edit 9 octobre 2015 <sub>2</sub><a aria-hidden="true" href="#edit-9-octobre-2015-2"><span class="icon icon-link"></span></a></h4>
<p>Fausse joie : avec le templating, c’est pareil… Voici le HTML généré par la même machine et le même code, en haut en dev' et en bas en prod' :</p>
<div class="hljs-code-div"><div class="hljs-line-numbers"><span></span><span></span><span></span></div><pre><code class="hljs language-html"><span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my_wonderfulbundle_product_galleryMedias_1_file"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"my_wonderfulbundle_product[galleryMedias][1][file]"</span> <span class="hljs-attr">accept</span>=<span class="hljs-string">"image/*"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"filestyle ajaxUpload"</span> <span class="hljs-attr">data-uri</span>=<span class="hljs-string">"/app_dev.php/media/_upload"</span> <span class="hljs-attr">data-target</span>=<span class="hljs-string">"uploads/medias"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"my_wonderfulbundle_product_galleryMedias_1_file"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"my_wonderfulbundle_product[galleryMedias][1][file]"</span> <span class="hljs-attr">required</span>=<span class="hljs-string">"required"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"ajaxUpload"</span> <span class="hljs-attr">data-uri</span>=<span class="hljs-string">"/app.php/media/_upload"</span> <span class="hljs-attr">data-target</span>=<span class="hljs-string">"uploads/medias"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span>></span>
</code></pre></div>
<p>Temporairement, j’ai rendu mon champ "à l’ancienne". Mais si quelqu’un avait un comportement similaire, qu’il comprenait la raison et qu’il avait la bonne solution au sens Symfony, je serais très intéressé.</p>