Comment ajouter ou enlever 1 année

Résolu

Bonjour,

J'ai développé un calendrier annuel dont voilà les sources :

index.php

<?php 
	namespace App;
  require_once __DIR__ . '/vendor/autoload.php';
  $year = new Year($_GET['year'] ?? null);
?>
<!DOCTYPE html>
<html lang="fr">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>Calendrier</title>
		<!-- Favicon -->
		<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
		<!-- Styles CSS -->
		<link rel="stylesheet" href="css/styles.css">
		<!-- Scripts -->
		<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" defer="defer"></script>
		<script src="js/date.prototype.js" defer></script>
		<script src="js/date.time.js" defer></script>
		<script src="js/calend.js" defer></script>
		<script src="js/jQuery.js" defer></script>
	</head>
	<body>
		<div class="container">
			<header>
				<div class="datetime">
					<span class="date"></span><br>
					<span class="num-day"></span>
					<span class="num-week"></span><br>
					<span class="reste"></span>
				</div>
				<h1><a href="/">Calendrier</a> <?= $year->year ?>  </h1>
				<div class="time"></div>
			</header>
			<nav>
				<button class="btn btn-primary" id="prev"><p><</p></button>
				<button class="btn btn-success" id="premier">Premier semestre</button>
				<button class="btn btn-success" id="second">Deuxième semestre</button>
				<button class="btn btn-primary" id="next"><p>></p></button>
			</nav>
			<section id="sect01">
				<?= $year->getFirstSem($year->year) ?>
			</section>
			<section id="sect02">
				<?= $year->getSecondSem($year->year) ?>
			</section>
		</div>
		<footer>
			<p>Copyright &copy; calendrier (2023-<span class="cpy"></span></span>). Tous droits réservés</p>
		</footer>
	</body>
</html>

La classe Year.php 

<?php 
namespace App;
use \DateTime;
use \DateInterval;
use \IntlDateFormatter;
use \DateTimeImmutable;

class Year {
	// Tableau des jours et des mois
	public $days   = ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'];
	public $months = [' ', 'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
										'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'];

	public int $year;
	public string $now;
	private $feries;

	// Variables
	private int $daysInMonths;
	private $source;

	/**
	 * Contructeur
	 * @param int|null $month [description]
	 * @param int|null $year  [description]
	 */
		public function __construct(?int $year = null)
		{
			if ($year === null) {
				$year = intval(date('Y'));
			}
			$this->year  = $year;
			$this->now = date('Y-m-d');

			// Tableau des jours fériés
			$this->feries = $this->getFeries($this->year);
		}

	/**
	 * Construction des lignes de source
	 * @return string
	 */
	public function getFirstSem($year): string
	{
		$date = new DateTime($year . '-01-01');
		for ($month = 1; $month <= 6; $month++) {
			$this->daysInMonths = $date->format('t');
			$this->source .= '<div class="calend">';
			$this->source .= 		'<div class="cal-top">';
			$this->source .= 			'<div class="top1">' . $this->months[$month] . '</div>';
			$this->source .= 			'<div class="top2">';
			$this->source .=				'<span class="caldat">date';
			$this->source .=				'</span>';
			$this->source .=				'<span class="calday">jour';
			$this->source .=				'</span>';
			$this->source .=				'<span class="calsem">sem</span>';
			$this->source .=				'</span>';
			$this->source .= 		'</div>';
			$this->source .=	'</div>';
			// $this->source .= '<div class="cal-det">';
			for ($day = 1; $day <= $this->daysInMonths; $day++) {
				if (in_array($date->format('Y-m-d'), $this->feries)) {
					$this->source .= '<div class="day green">';
				} elseif (($this->days[$date->format('w')] === 'Dimanche')) {
					$this->source .= '<div class="day red">';
				} elseif ($date->format('Y-m-d') === $this->now) {
					$this->source .= '<div class="day blue">';
				} else {
					$this->source .= '<div class="day">';
				}
				$this->source .= 	'<span class="cal_date">';
				$this->source .= 		$this->days[$date->format('w')];
				$this->source .= 	'</span>';
				$this->source .= 		$date->format('d');
				$this->source .= 	'</span>';
				$this->source .= 	'<span class="cal_num_day">';
				$this->source .= 		($date->format('z')+1) < 10 ? '0' . $date->format('z')+1 : $date->format('z')+1;
				$this->source .= 	'</span>';
				$this->source .= 	'<span class="cal_num_week">';
				$this->source .= 		$date->format('W');
				$this->source .= 	'</span>';
				$this->source .= '</div>';

				$date->add(new DateInterval('P1D'));
			}
			$this->source .= '</div>';
		}
		$this->source .= '</div>';
		return $this->source;
	}

	/**
	 * Construction des lignes de source
	 * @return string
	 */
	public function getSecondSem($year): string
	{
		$this->source = '';
		$date = new DateTime($year . '-07-01');
		for ($month = 7; $month <= 12; $month++) {
			$this->daysInMonths = $date->format('t');
			$this->source .= '<div class="calend">';
			$this->source .= 		'<div class="cal-top">';
			$this->source .= 			'<div class="top1">' . $this->months[$month] . '</div>';
			$this->source .= 			'<div class="top2">';
			$this->source .=				'<span class="caldat">date';
			$this->source .=				'</span>';
			$this->source .=				'<span class="calday">jour';
			$this->source .=				'</span>';
			$this->source .=				'<span class="calsem">sem</span>';
			$this->source .=				'</span>';
			$this->source .= 		'</div>';
			$this->source .=	'</div>';
			// $this->source .= '<div class="cal-det">';
			for ($day = 1; $day <= $this->daysInMonths; $day++) {
				if (in_array($date->format('Y-m-d'), $this->feries)) {
					$this->source .= '<div class="day green">';
				} elseif (($this->days[$date->format('w')] === 'Dimanche')) {
					$this->source .= '<div class="day red">';
				} elseif ($date->format('Y-m-d') === $this->now) {
					$this->source .= '<div class="day blue">';
				} else {
					$this->source .= '<div class="day">';
				}
				$this->source .= 	'<span class="cal_date">';
				$this->source .= 		$this->days[$date->format('w')];
				$this->source .= 	'</span>';
				$this->source .= 		$date->format('d');
				$this->source .= 	'</span>';
				$this->source .= 	'<span class="cal_num_day">';
				$this->source .= 		($date->format('z')+1) < 10 ? '0' . $date->format('z')+1 : $date->format('z')+1;
				$this->source .= 	'</span>';
				$this->source .= 	'<span class="cal_num_week">';
				$this->source .= 		$date->format('W');
				$this->source .= 	'</span>';
				$this->source .= '</div>';

				$date->add(new DateInterval('P1D'));
			}
			$this->source .= '</div>';
		}
		$this->source .= '</div>';
		return $this->source;
	}

	/**
	 * Liste des jours fériés
	 * @param  [type] $year [description]
	 * @return [type]       [description]
	 */
	public function getFeries($year)
	{
		// Tableau des jours fériés
		$feries = [$year . '-01-01', $year . '-05-01', $year . '-05-08', $year . '-07-14',
							 $year . '-08-15', $year . '-11-01', $year . '-11-11', $year . '-12-25'];

		// Date de base
		$easter = date('Y-m-d', easter_date($year));
		$easter = new DateTimeImmutable($easter);

		// Pâques
		$base   = new DateTime("$year-03-21");
		$days   = easter_days($year);
		$paques  = $base->add(new \DateInterval("P{$days}D"));

		// Dates liées à pâques
		$lpaq = $easter->add(new \DateInterval('P2D'));
		$asc = $easter->add(new \DateInterval('P40D'));
		$pent = $easter->add(new \DateInterval('P50D'));
		$lpent = $easter->add(new \DateInterval('P51D'));

		// Chargement du tableau
		array_push($feries, $paques->format('Y-m-d'));
		array_push($feries, $lpaq->format('Y-m-d'));
		array_push($feries, $asc->format('Y-m-d'));
		array_push($feries, $pent->format('Y-m-d'));
		array_push($feries, $lpent->format('Y-m-d'));

		return $feries;
	}

}

Comment puis-je ajouter ou soustraire une année en cliquant sur les boutons 'next' ou 'previous' ?

Merci de votre aide.

Cordialement
 

8 réponses

  1. Modérateur

    Bonjour,

    Il faudrait déjà que tes boutons déclenchent une action ...

    Soit par le biais d'un lien, soit par appel ajax.

    Une fois que tu auras mis ça en place, transmettre une variable qui contiendra deux variables : La date en cours et si il faut faire prev ou next sera facile.

    De là, tu pourras, dans ton php, récupérer ces deux variables et les utiliser pour ajouter ou soustraire ce que tu veux.


    0
    1. Effectivement,

      Voilà les lignes modifiées :

      <?php 
      	namespace App;
      	use \DateTime;
        require_once __DIR__ . '/vendor/autoload.php';
        $year = new DateTime();
        $year = $year->format('Y');
        $year = intval($year);
        if(isset($_POST['prev'])) {
        	$anne = $year;
        	$anne--;
        	var_dump($anne);
      	}
      	if(isset($_POST['next'])) {
        	$year++;
      	}
        $year = new Year($year);
      ?>
      
      
      <nav>
      				<form method="post">
      					<input class="btn btn-primary" name="prev" type="submit" value="Précédant">
      				</form>
      				<button class="btn btn-success" id="premier">Premier semestre</button>
      				<button class="btn btn-success" id="second">Deuxième semestre</button>
      				<form method="post">
      					<input class="btn btn-primary" name="next" type="submit" value="Suivant">
      				</form>
      			</nav>

      Le souci que j'ai maintenant, c'est qu'il ne le fait qu'une fois prev -> 2022, next->2024.

      J'ai dû mal faire quelque part.

      Si tu as une idée, je t'en saurai très reconnaissant.

      0
      1. Modérateur

        Comme je te l'ai dit, il faut passer DEUX variables à ton code

        le prev ou le next, comme tu as fais

        ET ... l'ANNEE affichée par ton calendrier pour qu'il sache sur quelle valeur il doit agir ...

        0
    2. Merci,

      Je ne veux que l'année, ça ne marche qu'une seule fois.

      Revoilà le code :

      <?php 
      	namespace App;
        require_once __DIR__ . '/vendor/autoload.php';
        $year = new Year($_GET['year'] ?? null);
        if(isset($_POST['prev'])) {
        	$year->year--;
        	$year = new Year($year->year);
      	}
      	if(isset($_POST['next'])) {
      		$year->year++;
      		$year = new Year($year->year);
      	}
      ?>
      0
      1. Modérateur

        Quand tu cliques sur tes boutons ... l'année change dans l'url ( là où tu as passé la variable ) ?

        Et pourquoi as tu .. d'un côté du POST .. et de l'autre .. du GET ?

        Si tu veux le faire en POST, il faut stocker l'année en cours dans ton formulaire ( dans un champ hidden éventuellement )

        0
    3. Merci,

      J'ai essayé de tout mettre en _GET, mais rien ne s'affiche dans l'url, pour cela, je saisis l'url.

      Je suis un peu débutant en php.

      merci de m'aider pour bien le coder. 

      0
      1. Modérateur

        De quelle façon envoies tu les données à ton code php ? (Quel est le code html ou js utilisé au niveau de tes boutons ?)


        0
        1. Je te renvois tout ça.

          1 - index.php

          <?php 
          	namespace App;
            require_once __DIR__ . '/vendor/autoload.php';
            $year = new Year($_GET['year'] ?? null);
            if(isset($_GET['prev'])) {
            	$year->year--;
            	$year = new Year($year->year);
          	}
          	if(isset($_GET['next'])) {
          		$year->year++;
          		$year = new Year($year->year);
          	}
          ?>
          <!DOCTYPE html>
          <html lang="fr">
          	<head>
          		<meta charset="utf-8">
          		<meta name="viewport" content="width=device-width, initial-scale=1.0">
          		<title>Calendrier</title>
          		<!-- Favicon -->
          		<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
          		<!-- Styles CSS -->
          		<link rel="stylesheet" href="css/styles.css">
          		<!-- Scripts -->
          		<script src="js/date.prototype.js" defer></script>
          		<script src="js/date.time.js" defer></script>
          		<script src="js/calend.js" defer></script>
          	</head>
          	<body>
          		<div class="container">
          			<header>
          				<div class="datetime">
          					<span class="date"></span><br>
          					<span class="num-day"></span>
          					<span class="num-week"></span><br>
          					<span class="reste"></span>
          				</div>
          				<h1><a href="">Calendrier</a> <?= $year->year ?>  </h1>
          				<div class="time"></div>
          			</header>
          			<nav>
          				<form method="get">
          					<input class="btn btn-primary" name="prev" type="submit" value="<">
          				</form>
          				<button class="btn btn-success" id="premier">Premier semestre</button>
          				<button class="btn btn-success" id="second">Deuxième semestre</button>
          				<form method="post">
          					<input class="btn btn-primary" name="next" type="submit" value=">">
          				</form>
          			</nav>
          			<section id="sect01">
          					<?= $year->getFirstSem($year->year) ?>
          			</section>
          			<section id="sect02">
          				<?= $year->getSecondSem($year->year) ?>
          			</section>
          		</div>
          		<footer>
          			<p>Copyright © calendrier (2023-<span class="cpy"></span></span>). Tous droits réservés</p>
          		</footer>
          	</body>
          </html>

          2 - calend.js (uniquement pour affichage de page)

          // Déclarations
          const first = document.querySelector('#premier'),
          second = document.querySelector('#second'),
          sect01 = document.querySelector('#sect01'),
          sect02 = document.querySelector('#sect02'),
          opt = { month: 'numeric' }
          month = new Date().toLocaleDateString('fr-FR', opt)
          
          // Afficher premier ou second semestre suivant le mois
          if (month <= 6) {
          	sect01.style.display = 'flex'
          	sect02.style.display = 'none'
          } else {	
          	sect01.style.display = 'none'
          	sect02.style.display = 'flex'
          }
          
          // Afficher premier semestre au click
          first.addEventListener('click', () => {
          	sect01.style.display = 'flex'
          	sect02.style.display = 'none'
          })
          second.addEventListener('click', () => {
          	sect01.style.display = 'none'
          	sect02.style.display = 'flex'
          })
          

          Je n'arrive pas à coder correctement les boutons 'Previous' et 'Next'.

          3 - composer.json

          {
              "name": "amaur/new-php",
              "description": "Calendrier",
              "type": "project",
              "license": "1.0.0",
              "authors": [
                  {
                      "name": "Amaury le Cour"
                  }
              ],
              "minimum-stability": "stable",
              "autoload": {
                  "psr-4": {
                      "App\\": "class/"
                  }
              },
              "require": {
                  "symfony/var-dumper": "^6.2"
              }
          }
          
          0
          1. Modérateur

            Tu utilises des <form  en POST pour transmettre tes données

            <form method="post">
            	<input class="btn btn-primary" name="next" type="submit" value=">">
            </form>

            Comme je te l'ai déjà dit ... il te suffirait d'y ajouter un input hidden contenant l'année "en cours"  pour ensuite pouvoir ajouter ou soustraire à cette année là ...


            0
            1. Merci pour tout.

              En fait, j'ai juste ajouté 2 méthodes à ma classe Year comme cela :

              /**
              	 * Envoit l'année suivante
              	 * @return Year
              	 */
              	public function nextYear(): Year
              	{
              		$year = $this->year + 1;
              
              		return new Year($year);
              	}
              
              	/**
              	 * Envoit l'année précédente
              	 * @return Year
              	 */
              	public function prevYear(): Year
              	{
              		$year = $this->year - 1;
              
              		return new Year($year);
              	}

              et dans index.php cela devient :

              <nav>
                 <a href="<?= $url ?>?year=<?= $year->prevYear()->year ?>" class="btn btn-primary">Prev</a>
                 <button class="btn btn-success" id="premier">Premier semestre</button>
                 <button class="btn btn-success" id="second">Deuxième semestre</button>
                 <a href="<?= $url ?>?year=<?= $year->nextYear()->year ?>" class="btn btn-primary">Next</a>
              </nav>

              $url = $_SERVER['PHP_SELF'];

              Cela marche exactement comme je le voulais.

              0
              1. Modérateur

                En GET avec un lien... Et en transmettant deux variables ...C'était aussi ma proposition...

                Pense a mettre le sujet en résolu.

                0