Snippets

Les snippets sont des bout de code.

Présenté ici de manière volontairement « brute », ces snippets ont vocation à servir d'aide mémoire.

N'hésitez-pas à poser un commentaire si vous rencontrez un problème avec un des éléments.

Vous pouvez utiliser la navigation via les tags présents sur la droite

  • Drupal 8 - Rediriger l'utilisateur lors de l'accès aux pages d'un type de contenu en particulier

    Posté le Mercredi 6 décembre 2017 - 09:41
    Dernière mise à jour le Mercredi 6 décembre 2017 - 19:00

    Ça vient à contresens du paradigme des noeuds, mais parfois on souhaite que les pages de détail d'un noeud d'un type de contenu en particulier ne soient pas accessible.

    Avec quelques adaptation, ceci peut aussi fonctionner pour les pages de terme de taxonomie.

    Voici comment faire :

    1ère étape, déclarer un services dans mon_module.services.yml

    1. services:
    2.   mon_module.node_cp_redirect:
    3.   class: Drupal\mon_module\EventSubscriber\NodeCPRedirect
    4.   tags:
    5.   - { name: event_subscriber }

    2ème étape, créer l'event subscriber: src/EventSubscriber/NodeCPRedirect.php dans le dossier de mon module.

    Ici je vais chercher à rediriger tous les noeuds de type « communiques_de_presse » vers la vue « view.front_communiques_de_presse.page », mais cela peut-être évidement n'importe quelle route.

    1. <?php
    2.  
    3. namespace Drupal\mon_module\EventSubscriber;
    4.  
    5. use Drupal\Core\Url;
    6. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    7. use Symfony\Component\HttpFoundation\RedirectResponse;
    8. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    9. use Symfony\Component\HttpKernel\KernelEvents;
    10.  
    11. class NodeCPRedirect implements EventSubscriberInterface {
    12.  
    13. public static function getSubscribedEvents() {
    14. return [KernelEvents::REQUEST => [['redirectionCommuniquesPresse']]];
    15. }
    16.  
    17. /**
    18.   * Redirection des contenus de type communique_de_presse vers la vue de listing.
    19.   */
    20. public function redirectionCommuniquesPresse(GetResponseEvent $event) {
    21. $request = $event->getRequest();
    22.  
    23. if ($request->attributes->get('_route') !== 'entity.node.canonical') {
    24. return;
    25. }
    26. if ($request->attributes->get('node')->getType() !== 'communique_de_presse') {
    27. return;
    28. }
    29. $response = new RedirectResponse(Url::fromRoute('view.front_communiques_de_presse.page')->toString(), 301);
    30. $event->setResponse($response);
    31. }
    32.  
    33. }

     

  • Drupal 8 - Views - Récupérer un formulaire exposé

    Posté le Vendredi 17 novembre 2017 - 11:18

    Pour un besoin spécifique, il fallait que je récupère un formulaire exposé de views pour l'afficher ailleurs.

    Il fallait en fait qu'à un endroit j'affiche les filtres exposés et à un autre le tri exposé.

    J'ai donc créé un bloc, qui récupère ce formulaire, masque un champ.

    Voici donc comment récupérer un formulaire exposé :

    1. $view_name = 'ma_vue';
    2. $view_display = 'page';
    3.  
    4. $view = \Drupal\views\Views::getView($view_name);
    5. $view->initHandlers();
    6. $view->setDisplay($view_display);
    7. $form_state = new \Drupal\Core\Form\FormState();
    8. $form_state->setFormState([
    9. 'view' => $view,
    10. 'display' => $view->display_handler->display,
    11. 'exposed_form_plugin' => $view->display_handler->getPlugin('exposed_form'),
    12. 'method' => 'get',
    13. 'rerender' => TRUE,
    14. 'no_redirect' => FALSE,
    15. 'always_process' => TRUE,
    16. ]);
    17.  
    18. // Ici j'ajoute une info pour connaitre le contexte si le formulaire est altéré
    19. // afin de distiguer cette instance de formulaire de la « normale ».
    20. $form_state->addBuildInfo('exposed_block', TRUE);
    21.  
    22. $form = \Drupal::formBuilder()->buildForm('Drupal\views\Form\ViewsExposedForm', $form_state);
    23.  
    24. // Je masque le champs qui ne m'intéresse pas
    25. $form['sort_by']['#access'] = FALSE;

    Dans le cadre d'un HOOK_form_alter je peux récupérer l'information "exposed_block" de la façon suivante :

    $form_state->getBuildInfo()['exposed_block']

     

     

  • Drupal 8 - Views - Changer le titre d'une vue en fonction du nombre de résultats

    Posté le Lundi 13 novembre 2017 - 09:07

    Utile dans le cadre d'une vue affichant des résultats d'une recherche via Search API :

    1. function MONMODULE_views_post_render(\Drupal\views\ViewExecutable $view) {
    2. if($view->storage->id() === 'NOM_MACHINE_VUE' && $view->current_display === 'NOM_MACHINE_AFFICHAGE') {
    3. $view->setTitle($view->getTitle() . ' (' . count($view->result) . ')');
    4. }
    5. }

     

  • Drupal - afficher en live le contenu du watchdog avec drush

    Posté le Mardi 31 octobre 2017 - 16:08
    Dernière mise à jour le Dimanche 12 novembre 2017 - 15:14

    Parfois on se retrouve avec un gros White Screen Of Death sur son site, et impossible de se connecter.

    Dans ce cas là il est pratique de pouvoir afficher en live le contenu du watchdog, c'est possible avec Drush et la commande watchdog-show :

    drush @alias watchdog-show --tail --full --count=50

    --tail affichera les nouvelles entrées du watchdog en direct

    --full pour afficher le détail des erreurs

    --count=50 permettra d'afficher les 50 lignes les plus récentes du watchdog.

    2017-10-31-16-13-09-Screenshot-01.jpg

    (Deux fois dans la journée que je recherche cette commande, au moins je saurai maintenant ou la retrouver...)

  • Exemple de fichier gitlab-ci.yml

    Posté le Dimanche 29 octobre 2017 - 17:27
    Dernière mise à jour le Samedi 11 novembre 2017 - 11:01

    .gitlab-ci.yml

    1. stages :
    2. - predeploy
    3. - deploy
    4. - postdeploy
    5. - scheduled
    6.  
    7.   prod_backup_db:
    8.   script:
    9. - ssh <a href="<a href="mailto:user@serveur">mailto:user@serveur</a>"><a href="mailto:user@serveur">user@serveur</a></a> 'drush @kg cr'
    10. - ssh <a href="<a href="mailto:user@serveur">mailto:user@serveur</a>"><a href="mailto:user@serveur">user@serveur</a></a> 'drush @kg sql-dump --gzip > "/home/site/db/`date +%Y-%m-%d_%H-%M-%S`-kgaut.net-$(hostname).sql.gz"'
    11.   only:
    12. - master
    13.   stage : predeploy
    14.   environment:
    15.   name: preprod
    16.  
    17.   prod_diff_git:
    18.   script:
    19. - ssh <a href="<a href="mailto:user@serveur">mailto:user@serveur</a>"><a href="mailto:user@serveur">user@serveur</a></a> 'bash -s' < scripts/deploy/2-diff.sh
    20.   only:
    21. - master
    22.   except:
    23. - schedules
    24.   stage : predeploy
    25.   environment:
    26.   name: preprod
    27.  
    28.   prod_diff_config:
    29.   script:
    30. - ssh <a href="<a href="mailto:user@serveur">mailto:user@serveur</a>"><a href="mailto:user@serveur">user@serveur</a></a> 'bash -s' < scripts/deploy/3-diff-config.sh
    31.   only:
    32. - master
    33.   except:
    34. - schedules
    35.   stage : predeploy
    36.   environment:
    37.   name: preprod
    38.  
    39.   prod_deploy:
    40.   script:
    41. - ssh <a href="<a href="mailto:user@serveur">mailto:user@serveur</a>"><a href="mailto:user@serveur">user@serveur</a></a> 'bash -s' < scripts/deploy/4-deploy.sh
    42.   only:
    43. - master
    44.   except:
    45. - schedules
    46.   stage : deploy
    47.   environment:
    48.   name: preprod
    49.  
    50.   dump:
    51.   only:
    52. - schedules
    53.   stage : scheduled
    54.   script:
    55. - ssh <a href="<a href="mailto:user@serveur">mailto:user@serveur</a>"><a href="mailto:user@serveur">user@serveur</a></a> 'find "/home/kgaut_net/db" -type f -mtime +"3" -delete'

    2-diff.sh

    1. #!/bin/bash
    2. set -e
    3. cd website
    4. if [[ $(git diff) ]]; then
    5. FILENAME="$(date +"%Y-%m-%d_%H-%M-%S")-diff.patch"
    6. git diff > "/home/site/diffs/$FILENAME"
    7. echo "---------------------------------";
    8. echo "modifications en prod detectées, patch créé : $FILENAME";
    9. echo "Modifications de fichier en prod detectées, patch créé" | mail -s "Fichiers modifiés" -a "/home/site/diffs/$FILENAME" <a href="<a href="mailto:moi@email.com">mailto:moi@email.com</a>"><a href="mailto:moi@email.com">moi@email.com</a></a>
    10. echo "Liste des fichiers modifiés : ";
    11. echo $(git diff --name-only)
    12. echo "---------------------------------";
    13. git checkout ./
    14. else
    15. if [[ $(git ls-files --others --exclude-standard) ]]; then
    16. echo "---------------------------------";
    17. echo "Fichiers non versionnés : "
    18. echo $(git ls-files --others --exclude-standard)
    19. echo "---------------------------------";
    20. FAIL;
    21. else
    22. echo "Pas de modification en prod à signaler"
    23. fi
    24. fi

    3-diff-config.sh

    1. #!/bin/bash
    2. set -e
    3.  
    4. cd /home/site/website
    5. drush @kg cr
    6. drush @kg config-export sync -y
    7. if [[ $(git diff files/config/) ]]; then
    8. echo "---------------------------------";
    9. FILENAME="$(date +"%Y-%m-%d_%H-%M-%S")-config.patch"
    10. git diff files/config/ > "/home/site/diffs/$FILENAME"
    11. echo "Modifications de configuration en prod detectées, patch créé : $FILENAME";
    12. echo "Configuration modifiée, patch créé" | mail -s "Configuration modifiée" -a "/home/site/diffs/$FILENAME" <a href="<a href="mailto:contact+kgn@kgaut.net">mailto:contact+kgn@kgaut.net</a>"><a href="mailto:contact+kgn@kgaut.net">contact+kgn@kgaut.net</a></a>
    13. git checkout ./
    14. echo "---------------------------------";
    15. #FAIL;
    16. fi
    17.  
    18. cd /home/site/website/files/config
    19. if [[ $(git ls-files --others --exclude-standard) ]]; then
    20. echo "---------------------------------";
    21. FILENAME="$(date +"%Y-%m-%d_%H-%M-%S")-config.tar"
    22. echo "Config en prod non versionnée : "
    23. echo $(git ls-files --others --exclude-standard)
    24. tar -zcvf "/home/site/diffs/$FILENAME" ./
    25. echo "Archive crée : $FILENAME";
    26. echo "Configuration modifiée, non versionnée, patch créé" | mail -s "Configuration non versionnée" -a "/home/site/diffs/$FILENAME" <a href="<a href="mailto:contact+kgn@kgaut.net">mailto:contact+kgn@kgaut.net</a>"><a href="mailto:contact+kgn@kgaut.net">contact+kgn@kgaut.net</a></a>
    27. rm ./*/*.yml
    28. git checkout ./
    29. echo "---------------------------------";
    30. #FAIL;
    31. fi

    4-deploy.sh

    1. #!/bin/bash
    2. set -e
    3. cd /home/site/website
    4. git pull
    5. composer install --no-dev
    6. drush @kg updb -y
    7. drush @kg entup -y
    8. drush @kg updb -y
    9. drush @kg config-import sync -y
    10. gulp prod
    11. drush @kg cr
  • Drupal 8 - Formulaire - « ajouter un élément » et « supprimer un élément »

    Posté le Lundi 9 octobre 2017 - 17:19
    Dernière mise à jour le Mardi 5 décembre 2017 - 09:17

    Voici comment dans un formulaire custom D8, avoir un ensemble de champ "multiples" dans un formulaire de config par exemple.

    drupal8-formulaire-add-more.jpg

    Dans mon exemple je n'ai que le champ « titre », mais c'est simplement pour alléger le snippet.

    Le code en question :

    1. <?php
    2.  
    3. namespace Drupal\monmodule\Form;
    4.  
    5. use Drupal\Core\Form\ConfigFormBase;
    6. use Drupal\Core\Form\FormStateInterface;
    7. use Drupal\file\Entity\File;
    8.  
    9. /**
    10.  * Class PopoteConfigForm.
    11.  */
    12. class HomepageConfigForm extends ConfigFormBase {
    13.  
    14. protected function getEditableConfigNames() {
    15. return [
    16. 'monmodule.homepage',
    17. ];
    18. }
    19.  
    20. public function getFormId() {
    21. return 'homepage_config_form';
    22. }
    23.  
    24. public function buildForm(array $form, FormStateInterface $form_state) {
    25. $config = $this->config('monmodule.homepage');
    26. $pomoted_items = $config->get('promoted', []);
    27. $number_promoted = $form_state->getValue('number_promoted', count($pomoted_items));
    28. $removed = $form_state->getValue('removed_promoted', []);
    29.  
    30. $form['number_promoted'] = [
    31. '#type' => 'value',
    32. '#value' => $number_promoted,
    33. ];
    34. $form['removed'] = [
    35. '#type' => 'value',
    36. '#value' => $removed,
    37. ];
    38. $form['promoted'] = [
    39. '#type' => 'fieldset',
    40. '#title' => t("À la une"),
    41. '#tree' => TRUE,
    42. ];
    43. for ($i = 1; $i <= $number_promoted; $i++) {
    44. $item = array_shift($pomoted_items);
    45. if (in_array($i, $removed)) {continue;}
    46. $form['promoted'][$i] = [
    47. '#type' => 'fieldset',
    48. '#title' => t("À la une #@i", ['@i' => $i]),
    49. ];
    50. $form['promoted'][$i]['title'] = [
    51. '#type' => 'textfield',
    52. '#title' => $this->t("Titre"),
    53. '#default_value' => $item['title'],
    54. ];
    55. $form['promoted'][$i]['remove_' . $i] = [
    56. '#type' => 'submit',
    57. '#value' => t("Supprimer l'élément #@i", ['@i' => $i]),
    58. '#submit' => ['::removeItem'],
    59. '#attributes' => [
    60. 'class' => ['button--danger'],
    61. 'data-toRemove' => $i,
    62. ]
    63. ];
    64. }
    65. $form['promoted']['add_item'] = [
    66. '#type' => 'submit',
    67. '#value' => t('Ajouter un autre élément'),
    68. '#submit' => ['::addPromotedItem'],
    69. ];
    70.  
    71. return parent::buildForm($form, $form_state);
    72. }
    73.  
    74. public function addPromotedItem(array &$form, FormStateInterface $form_state) {
    75. $form_state->setValue('number_promoted', $form_state->getValue('number_promoted') + 1);
    76. $form_state->setRebuild();
    77. }
    78.  
    79. public function removeItem(array &$form, FormStateInterface $form_state) {
    80. $removed = $form_state->getValue('removed_promoted', []);
    81. $removed[] = $form_state->getTriggeringElement()['#attributes']['data-toRemove'];
    82. $form_state->setValue('removed_promoted', $removed);
    83. $form_state->setRebuild();
    84. }
    85.  
    86. public function submitForm(array &$form, FormStateInterface $form_state) {
    87. parent::submitForm($form, $form_state);
    88. $parsed = [];
    89. $promoted = $form_state->getValue('promoted');
    90. foreach ($promoted as $promoted_item) {
    91. if(is_array($promoted_item)) {
    92. $parsed[] = $promoted_item;
    93. }
    94. }
    95. $this->config('monmodule.homepage')->set('promoted', $parsed)->save();
    96. }
    97. }

     

     
  • Drupal 8 - Accèder à $_GET et $_POST

    Posté le Lundi 2 octobre 2017 - 10:02
    Dernière mise à jour le Lundi 13 novembre 2017 - 13:58

    Récupérer $_GET['test'] :

    $test = \Drupal::request()->query->get('test');

     

    Récupérer $_POST['test'] :

    $test = \Drupal::request()->request->get('test');

     

    Récupérer un tableau associatif avec toutes les variables $_GET :

    $variables_get = \Drupal::request()->query->all();

     

    Récupérer un tableau associatif avec toutes les variables $_POST :

    $variables_post = \Drupal::request()->request->all();

     

  • Drupal 8 - Définir l'item de menu actif en fonction du type de noeud

    Posté le Mercredi 20 septembre 2017 - 17:48
    Dernière mise à jour le Vendredi 17 novembre 2017 - 17:04

    Sur ce site, j'ai trois types de contenu :

    • Article
    • Snippet
    • Réalisation

    Pour chacun de ces trois types de contenu, j'ai une vue (View) de listing qui correspond (cf le menu ci-dessus).

    Par défaut quand on est sur la vue de listing des snippets par exemple, on a bien l'élément de menu "Snippets" qui est marqué comme actif, par contre quand on va sur le détail d'un snippet, on perd cette information. Nous allons voir comment sélectionner le menu item qui doit être actif en fonction du type de contenu sur lequel on se trouve.

    1ère étape : surcharger le service MenuActiveTrail

    dans mon module « kgaut » je créé le fichier KgautMenuActiveTrail.php dans le dossier src/Menu avec le contenu suivant :

    1. <?php
    2.  
    3. namespace Drupal\kgaut\Menu;
    4.  
    5. use Drupal\Core\Menu\MenuActiveTrail;
    6. use Drupal\node\NodeInterface;
    7.  
    8. /**
    9.  * Extend the MenuActiveTrail class.
    10.  */
    11. class KgautMenuActiveTrail extends MenuActiveTrail {
    12.  
    13. /**
    14.   * {@inheritdoc}
    15.   */
    16. public function getActiveLink($menu_name = NULL) {
    17. // Call the parent method to implement the default behavior.
    18. $found = parent::getActiveLink($menu_name);
    19.  
    20. // If a node is displayed, load the default parent menu item
    21. // from the node type's menu settings and return it instead
    22. // of the default one.
    23. $node = $this->routeMatch->getParameter('node');
    24.  
    25. if ($node instanceof NodeInterface) {
    26. $bundle = $node->bundle();
    27. switch ($bundle) {
    28. case 'article':
    29. //Ici je demande à recherche le menu item qui utilise la route correspondant à mon type de contenu
    30. $links = $this->menuLinkManager->loadLinksByRoute('view.front_articles.page', [], $menu_name);
    31. break;
    32.  
    33. case 'snippet':
    34. $links = $this->menuLinkManager->loadLinksByRoute('view.front_snippets.page', [], $menu_name);
    35. break;
    36.  
    37. case 'realisation':
    38. $links = $this->menuLinkManager->loadLinksByRoute('view.front_realisations.page', [], $menu_name);
    39. break;
    40. }
    41.  
    42. if (isset($links) && $links) {
    43. $found = reset($links);
    44. }
    45. }
    46. return $found;
    47. }
    48. }

    C'est bien beau, mais maintenant il faut signaler à Drupal que l'on a surchargé un de ses services. Pour cela il faut créer le fichier src/MonModuleServiceProvider.php (attention c'est normé !) Dans mon cas j'ai donc créé le fichier KgautServiceProvider.php dans le dossier src de mon module kgaut (oui je suis très égocentrique).
    En voici le contenu :

    1. <?php
    2. /**
    3.  * @file
    4.  * Contains Drupal\kgaut\KgautServiceProvider.
    5.  */
    6.  
    7. namespace Drupal\kgaut;
    8.  
    9. use Drupal\Core\DependencyInjection\ContainerBuilder;
    10. use Drupal\Core\DependencyInjection\ServiceProviderBase;
    11.  
    12. class KgautServiceProvider extends ServiceProviderBase {
    13.  
    14. /**
    15.   * {@inheritdoc}
    16.   */
    17. public function alter(ContainerBuilder $container) {
    18. $container->getDefinition('menu.active_trail')->setClass('Drupal\kgaut\Menu\KgautMenuActiveTrail');
    19. }
    20.  
    21. }

    Un petit vidage de cache plus tard, et on est bon !