Semaine initiée au lundi - problème jour férié

Ellya
Invité n'ayant pas de compte PHPfrance

23 janv. 2020, 18:41

Bonjour !

J'ai besoin d'aide sur un point précis : j'ai un menu qui s'affiche dans un tableau et qui est initialisé au lundi.
Cependant, quand le lundi est férié, plus rien ne s'affiche. J'ai donc voulu créer un lundi vide quand celui-ci
est férié pour qu'il passe au mardi et s'affiche tout de même, sans succès pour l'instant.

Une petite idée du code :

    define("SECPJR", 86400);
		$now = time();
		$njour = (int) ($now / SECPJR);
		$nojour = date("w", $now);
		$lun = $now - (($nojour - 1) * SECPJR);
		$date_lundi = date("ymd", $lun);
		$id = $_GET['menu-repas'] . '-' . $date_lundi;
		unset ($_GET);
		header ( "location: ../../../menu-repas/" . $id  );

   //----------------------------------------------------------------------------
  //    Insert les données des menus dans la BDD à partir de $data_menus
  //----------------------------------------------------------------------------
  function sql_insert_data_menus() {
    global $error, $data_menus;

      //-----  Boucle de création des menus -----
      // On boucle sur chaque ville-typeConvive
      foreach ($data_menus as $ville_convive => $menus_ville_convive) {
        $ferie = false;
        // On boucle sur chaque jour
        foreach ($menus_ville_convive as $date => $menus_date) {
          // On teste si le jour est un lundi (1) --> si oui on lance la création du menu HTML
          // La date est au format ymd-N : 20181113-1
          $dateN = explode("-", $date) [1]; // jour de la semaine
          $dateYmd = explode("-", $date) [0]; // date au format ymd

// si lundi : $dateN!=='1' est un jour férié : $ferie==true,
// alors on déclare un jour férié et on passe au jour suivant : $dateN!=='2'

          if ($dateN == "1" || ($dateN == "2" && $ferie == true) ) {
            if ($dateN == "2") {
              $dateDay = substr($dateYmd, 4, 2);
              $dateDay = intval($dateDay) - 1;
              $lundi_ferieYmd = substr($dateYmd, 0, 4).$dateDay;
              $dateYmd = $lundi_ferieYmd;
              print($dateYmd);
            }
            $post_name = $ville_convive . "-" . $dateYmd;
            if (explode('-', $post_name)[2] == "clsh") {
              $post_name= rename_pdf_clsh($post_name)."-".$dateYmd;              
            }
            //----- Fabrication du menu au format html
            $ferie = false;
            $html_menu = get_html_menu($ville_convive, $dateYmd);
            //----- On échappe les caractères spéciaux pour l'insertion en BDD
            $html_menu = mysqli_real_escape_string ($mysqli , $html_menu);
            //----- Titre du menu
            $date_menu = DateTime::createFromFormat ( "ymd" , $dateYmd);
            $titre_menu = "Menu " . ucfirst(explode("-", $ville_convive) [0]) . " " .
                          ucfirst(explode("-", $ville_convive) [1]) . ", Semaine " . $date_menu->format("W") . ", du " .
                          $date_menu->format("d/m/Y");
            $now = date('Y-m-d H:i:s');
            $nowgmt = gmdate('Y-m-d H:i:s');
            $guid = "";
            
            } else {
              $ferie = true;
            }

           }
      }
      $mysqli->close();
    }

Merci d'avance et bonne soirée !

Avatar du membre
Mammouth du PHP | 1609 Messages

23 janv. 2020, 19:12

Salut, j'ai essayé de comprendre mais non je comprends pas. Tu devrais probablement essayer de clarifier ta demande.
Développeur web depuis + de 20 ans

Ellya
Invité n'ayant pas de compte PHPfrance

24 janv. 2020, 10:35

Bonjour,

Je suis désolé si je ne suis pas assez clair ! Je vais essayer de reprendre.

J'ai un tableau avec un menu de repas de la semaine du lundi au vendredi.
Dans le code, tout se base sur le premier jour de la semaine pour afficher les menus : le lundi.
Du coup, quand le lundi est férié et donc le fichier vide au lundi, plus rien ne s'affiche !

J'essaie donc de rajouter une partie pour, si le lundi est vide (férié) alors qu'il passe au mardi pour tout de même afficher la suite du menu.

J'espère que je suis plus clair et vous remercie d'avance pour votre aide !

Avatar du membre
Mammouth du PHP | 1609 Messages

24 janv. 2020, 12:22

Re, dans ce cas, il serait peut être plus intéressant de voir le code qui affiche le menu. Plutôt que de créer un menu vide tu peux surement corriger cette partie pour qu'elle n'ignore pas toute la semaine quand le lundi est férié.
Développeur web depuis + de 20 ans

Ellya
Invité n'ayant pas de compte PHPfrance

24 janv. 2020, 13:22

En effet, il serait peut-être plus simple de l'intégrer directement au menu !

define("SECPJR", 86400);
$now = time();
$njour = (int) ($now / SECPJR);
$nojour = date("w", $now);
$lun = $now - (($nojour - 1) * SECPJR);
$date_lundi = date("ymd", $lun);

//----------------------------------------------------------------------------
  //    Génère le tableau html des menus de la semaine pour une ville,
  //      un type convive et une semaine donnée
  //      - $ville_convive : La ville et le type de convive du menu à générer
  //      - $dateYmd : la date du lundi de la semaine à générer
  //    Exploite la var globale $data_menus
  //----------------------------------------------------------------------------
  function get_html_menu($ville_convive, $dateYmd) {
    global $data_menus;  // ville_convive - date - plats
    $menus_ville_convive = $data_menus[$ville_convive];

    $html = '<div class="menu"><table><thead><tr>';
    // 1ère ligne du tableau : en-tête
    $html .= html_th("");
    $html .= html_th("Repas & catégories");
    // On recherche les dates des 7 jours de la semaine
    $key_dates = array();
    $date = DateTime::createFromFormat("ymd", $dateYmd);
    for ($n = 0; $n < 7; $n++) {
      $html .= html_th( strftime("%A %e/%m", $date->getTimestamp()));
      $key_dates[] = $date->format("ymd-N");
      $date->add(new DateInterval("P1D"));
    }
    $html .= "</tr></thead>";
    $html .= "<tbody>";

    // On boucle sur chaque type de plat -> 1 ligne par type de plat
    foreach (TYPES_PLAT as $type_repas => $types_plat) {
      $prem_col = true;
      //--- 2ème colonne : type de plat
      foreach ($types_plat as $type_plat) {
        $html .= "<tr>";
        //--- 1ère colonne : type de repas
        if ($prem_col) {
          $rowspan = count($types_plat);
          $html .= html_td($type_repas, $rowspan);
        }
        //--- 2ème colonne : type de plat
        $html .= html_td($type_plat);
        //--- 3ème à 7ème colonne : chaque jour de la semaine
        foreach ($key_dates as $key_date) {
          $plat = false;
          $menu_date = null;
          $menu_ville_clsh = null;
          $ville_clsh_name = $ville_convive."-clsh";
          // --- Si le convive posséde des menus à la date $key_date
          //     alors le menu affiché est celui-ci
          if (key_exists($key_date, $menus_ville_convive)) {
            $menu_date = $menus_ville_convive[$key_date];
          } 
          // --- Si le clsh du convive posséde des menus à la date $key_date
          //     alors la variable $menu_ville_clsh est initialisée.
          if (key_exists($ville_clsh_name, $data_menus) && key_exists($key_date, $data_menus[$ville_clsh_name])) {
            $menu_ville_clsh = $data_menus[$ville_clsh_name][$key_date];
          }
          // --- Si le convive  et son clsh possédent des menus à la date $key_date
          //     alors le menu date est l'assemblage du menu des 2 convives.
          if (isset($menu_ville_clsh) && isset($menu_date)) {
            $menu_date = array_merge($menu_ville_clsh, $menu_date);
          } else if (isset($menu_ville_clsh) && !isset($menu_date)) {
            $menu_date = $menu_ville_clsh;
          }
          if (isset($menu_date)) {
            $plat = array_key_exists( $type_plat, $menu_date ) ? $menu_date[$type_plat] : false;
            if ( $plat ) {
              // On récupère les composants du plat
              $html .= get_html_plat($plat);
            } else {
              // Sinon le plat n'existe pas : on affiche vide
              $html .= html_td("");
            }
          } else {
            // Sinon pas de menu pour cette date là : on affiche vide
            $html .= html_td("");
          }
        }
        
        $html .= "</tr>";
        $prem_col = false;
      }
    }
    $html .= "</tbody></table></div>";
    return $html;
  }

Merci pour ton aide !

Avatar du membre
Mammouth du PHP | 1609 Messages

24 janv. 2020, 13:33

Bah à première vu y a rien dans ce code qui empêche la génération du menu si lundi est férié, dans le pire des cas tu devrais au moins avoir l'entête du tableau. Où est appelée la fonction get_html_menu ?
Développeur web depuis + de 20 ans

Ellya
Invité n'ayant pas de compte PHPfrance

24 janv. 2020, 15:14

Elle n'est appelée qu'au début :

function get_html_menu($ville_convive, $dateYmd) {}

Quand je charge un fichier xml avec un lundi férié, la page des menus devient introuvable.

Avatar du membre
Mammouth du PHP | 1609 Messages

24 janv. 2020, 15:47

Ca c'est pas un appel de fonction c'est une déclaration de fonction. Comme ça tout seul ça ne fait rien. Tu dois avoir quelque part dans tes codes un appel à la fonction de la forme get_html_menu($ville_convive, $dateYmd); (sans le function devant...).
// déclartion - ici le code de la fonction ne s'exécute pas, il est juste déclaré
function toto() { echo 'toto'; }

// appel - ici le code de la fonction s'exécute et écris toto
toto();

EDIT : je vois bien un appel à la fonction get_html_menu dans sql_insert_data_menu ici :
$html_menu = get_html_menu($ville_convive, $dateYmd);
Donc à priori il y a bien un problème au moment de l'insertion en base. La variable $ferie était-elle déjà présente où est ce toi qui l'as ajoutée ? Comment était le code original qui posait problème ? Parce que d'après ce que je vois, tu n'as pas à te soucier de savoir si le lundi est férié ou pas. Tu as juste à déterminer la date du lundi de $menus_ville_convive et à appeler get_html_menu avec.
Développeur web depuis + de 20 ans

Ellya
Invité n'ayant pas de compte PHPfrance

24 janv. 2020, 16:44

La variable $ferie a été ajouté suite au problème mais pas par moi non plus.
Voici une version antérieure :

  //----------------------------------------------------------------------------
  //    Insert les données des menus dans la BDD  à partir de $data_menus
  //----------------------------------------------------------------------------
  function sql_insert_data_menus() {
    global $error, $data_menus;

      //-----  Boucle de création des menus -----
      // On boucle sur chaque ville-typeConvive
      foreach ($data_menus as $ville_convive => $menus_ville_convive) {
        // On boucle sur chaque jour
        foreach ($menus_ville_convive as $date => $menus_date) {
          // On teste si le jour est un lundi (1) --> si oui on lance la création du menu HTML
          // La date est au format ymd-N : 20181113-1
          $dateN = explode("-", $date) [1]; // jour de la semaine
          $dateYmd = explode("-", $date) [0]; // date au format ymd

          if ($dateN == "1") {
            $post_name = $ville_convive . "-" . $dateYmd;
            //----- Fabrication du menu au format html
            $html_menu = get_html_menu($ville_convive, $dateYmd);
            //----- On échappe les caractères spéciaux pour l'insertion en BDD
            $html_menu = mysqli_real_escape_string ($mysqli , $html_menu);
            //----- Titre du menu
            $date_menu = DateTime::createFromFormat ( "ymd" , $dateYmd);
            $titre_menu = "Menu " . ucfirst(explode("-", $ville_convive) [0]) . " " .
                          ucfirst(explode("-", $ville_convive) [1]) . ", Semaine " . $date_menu->format("W") . ", du " .
                          $date_menu->format("d/m/Y");
            $now = date('Y-m-d H:i:s');
            $nowgmt = gmdate('Y-m-d H:i:s');
            $guid = ""; // A compléter

            // Commandes DELETE : On supprime le précédent Menu de même ville/convive/date s'il existe
            $format_sql = "DELETE wp_postmeta FROM wp_posts INNER JOIN wp_postmeta ON (wp_postmeta.post_id = wp_posts.id) " .
                          " WHERE wp_posts.post_name = '%s'; ";
            $sql = sprintf($format_sql, $post_name);
            if ( !$mysqli->query($sql) ) {
              error("Erreur SQL : $mysqli->error");
            }
            $format_sql = "DELETE FROM wp_posts WHERE wp_posts.post_name = '%s'; ";
            $sql = sprintf($format_sql, $post_name);
            if ( !$mysqli->query($sql) ) {
              error("Erreur SQL : $mysqli->error");
            }
            // Commande INSERT du nouveau menu
            $format_sql = "INSERT INTO wp_posts (post_date, post_date_gmt, post_content, post_title, post_excerpt, post_status, comment_status, ping_status, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_content_filtered, post_parent, guid, menu_order, post_type, comment_count ) " .
                  " VALUES ('%s', '%s', '%s', '%s', '', 'publish', 'closed', 'closed', '%s', '', '', '%s', '%s', '', 0, '%s', 0, 'menu-repas', 0);" ;
            $sql = sprintf($format_sql, $now , $nowgmt, $html_menu, $titre_menu, $post_name, $now , $nowgmt, $guid);
            if ( !$mysqli->query($sql) ) {
              error("Erreur SQL : $mysqli->error");
            } else {
              msg ( sprintf("Insertion dans la BDD du menu : %s", $titre_menu) );
            }
          }
        }
      }
      $mysqli->close();
    }
  }

Avatar du membre
Mammouth du PHP | 1609 Messages

24 janv. 2020, 16:50

Ouep, ben y a pas de question de lundi férié dans ce code. La seule chose qui bloque la création du menu c'est si la variable $date du foreach ($menus_ville_convive as $date => $menus_date) n'est pas un lundi. Le menu n'étant généré que si $dateN == "1".

Donc je pense que pour la semaine ou vous avez un problème c'est simplement que la date dans $date n'est pas un lundi. Alors après d'où vient la variable $menus_ville_convive et comment sont définis ses index ? Si au final c'est une date enregistrée dans la base de données, peut être simplement modifiez la date pour sélectionner le lundi de la semaine.
Développeur web depuis + de 20 ans

Ellya
Invité n'ayant pas de compte PHPfrance

24 janv. 2020, 17:11

Oui parce que quand le lundi est férié il ne doit pas exister dans le fichier et donc la date ne commence pas au 1.

  function get_html_menu($ville_convive, $dateYmd) {
    global $data_menus;  // ville_convive - date - plats

    $menus_ville_convive = $data_menus[$ville_convive];

    if($ville_convive == "m-e" or $ville_convive == "m_c_e" ){
        $menus_ville_convive = $data_menus["m-e"] + $data_menus["m_c_e"];
      } elseif($ville_convive =="m-m"){
        $menus_ville_convive = $data_menus[$ville_convive] + $data_menus["m_c_m"];
      } elseif($ville_convive == "b-e"){
        $menus_ville_convive = $data_menus[$ville_convive] + $data_menus["b_c_e"];
      } elseif($ville_convive == "b-m"){
        $menus_ville_convive = $data_menus[$ville_convive] + $data_menus["b_c_m"];
    }


    $html = '<div class="menu"><table><thead><tr>';
    // 1ère ligne du tableau : en-tête
    $html .= html_th("");
    $html .= html_th("Repas & catégories");
    // On recherche les dates des 7 jours de la semaine
    $key_dates = array();
    $date = DateTime::createFromFormat("ymd", $dateYmd);
    for ($n = 0; $n < 7; $n++) {
      $html .= html_th( strftime("%A %e/%m", $date->getTimestamp()));
      $key_dates[] = $date->format("ymd-N");
      $date->add(new DateInterval("P1D"));
    }
    $html .= "</tr></thead>";
    $html .= "<tbody>";

    // On boucle sur chaque type de plat -> 1 ligne par type de plat
    foreach (TYPES_PLAT as $type_repas => $types_plat) {
      $prem_col = true;
      //--- 2ème colonne : type de plat
      foreach ($types_plat as $type_plat) {
        $html .= "<tr>";
        //--- 1ère colonne : type de repas
        if ($prem_col) {
          $rowspan = count($types_plat);
          $html .= html_td($type_repas, $rowspan);
        }
        //--- 2ème colonne : type de plat
        $html .= html_td($type_plat);
        //--- 3ème à 7ème colonne : chaque jour de la semaine
        foreach ($key_dates as $key_date) {
          if (array_key_exists( $key_date, $menus_ville_convive )) {
            $menu_date = $menus_ville_convive[$key_date];
            $plat = array_key_exists( $type_plat, $menu_date ) ? $menu_date[$type_plat] : false;
            if ( $plat ) {
              // On récupère les composants du plat
              $html .= get_html_plat($plat);
            } else {
              // Sinon le plat n'existe pas : on affiche vide
              $html .= html_td("");
            }
          } else {
            // Sinon pas de menu pour cette date là : on affiche vide
            $html .= html_td("");
          }
        }
        $html .= "</tr>";
        $prem_col = false;
      }
    }
    $html .= "</tbody></table></div>";
    return $html;
  }

Avatar du membre
Mammouth du PHP | 1609 Messages

24 janv. 2020, 17:20

Je sais pas d'où tu as ressorti ce code, une deuxième fonction get_html_menu différente de la précédente, mais à priori c'est pas ça qui nous intéresse. Ce qui nous intéresse c'est la global $data_menus qui est utilisée dans la fonction sql_insert_data_menus. Comment est construit ce tableau ?
Développeur web depuis + de 20 ans

Avatar du membre
Mammouth du PHP | 1609 Messages

24 janv. 2020, 20:55

En fait si tu veux outrepasser le teste du lundi et comme la fonction get_menu_html attend un lundi en paramètre, il suffit de modifier la date pour récupérer le lundi précédent lorsque la date n'est pas un lundi. En partant de la version non modifiée du script :
foreach ($menus_ville_convive as $date => $menus_date) {
  // On teste si le jour est un lundi (1) --> si oui on lance la création du menu HTML
  // La date est au format ymd-N : 20181113-1
  $dateN = explode("-", $date) [1]; // jour de la semaine
  $dateYmd = explode("-", $date) [0]; // date au format ymd

  // si le jour n'est pas un lundi, définir la date au lundi précédent
  if ($dateN != 1) {
    $date = DateTime::createFromFormat( "Ymd" , $dateYmd);
    $date->sub(new DateInterval('P'.($dateN - 1).'D'));

    $dateN = 1;
    $dateYmd = $date->format('Ymd');
  }

  // supprimer ce teste qui ne sert plus
  // if ($dateN == "1") {

Le risque c'est d'avoir un effet de bord de menus qui s'affichent alors qu'ils ne devraient pas car ce teste ne doit pas être la sans raison, non ?
Développeur web depuis + de 20 ans

Ellya
Invité n'ayant pas de compte PHPfrance

30 janv. 2020, 10:35

Merci beaucoup, je vais tester ça ! (Et désolé pour la réponse tardive)