Bonjour,

Je travaille la première partie de cet excellent tuto sur la POO et les tests.

En résumé (des codes ci-dessous):
- 1 classe SessionStockage qui implémente l'interface Stockage
- 1 classe Product qui implémente l'interface Vendable
- 1 classe Panier qui utilise les 2 interfaces ci-dessus.
- 1 index.php qui créé/manipule des objets issus de ces 3 classes

Ce que je comprends en manipulant des objets issus de ces 3 classes et leurs méthodes :
La modification d'un produit par une méthode de sa classe engendre bien une modification du panier,
La modification d'un produit par une méthode de la classe SessionStockage engendre bien une modification du panier.
C'est probablement logique du fait que la classe Panier utilise les interfaces des 2 classes SessionStockage et Product.

J'ai certes encore besoin de mâcher et digérer ce tuto mais un point me chiffonne cependant :

Comment engendrer cette relation inverse : Si je modifie l'attribut d'un produit par une des méthodes de la classe SessionStockage, j'obtiens bien la mise à jour du panier grâce à l'interface, mais comment obtenir simultanément la modification de l'attribut du produit (de la classe Product) ?


J'espère que la question est aussi claire que le tuto...

Merci d'avance.


En annexe, ci-joints les codes (peu de différences vs. le tuto) :
CLASSE SESSIONSTOCKAGE
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# ##############################################################################
# INTERFACES
# ##############################################################################
	interface Stockage
	{
		// interface utilisée par la classe Panier
		public function set($nom, $prix);
		public function delete($nom);
		public function flush_cart();
		public function total();
	}
 
# ##############################################################################
# CLASSE
# ##############################################################################
 
	class SessionStockage implements Stockage
	{
		protected $_session;
		protected $_namespace;
 
		public function __construct($namespace = "default")
		{
			$this->_namespace = (string)$namespace;
			@session_start();
			if (!isset($_SESSION[$this->_namespace])) {
				$_SESSION[$this->_namespace] = array();
			}
			$this->_session = &$_SESSION[$this->_namespace];
		}
 
		public function set($nom, $prix)
		{
			if (!isset($this->_session[$nom])) {
				$this->_session[$nom] = 0;
			}
			$this->_session[$nom] += abs((float)$prix);
			return $this;
		}
 
		public function delete($nom)
		{
			if (isset($this->_session[$nom])) {
				unset($this->_session[$nom]);
			}
			return $this;
		}
 
		public function total()
		{
			return array_sum($this->_session);
		}
 
		public function flush_cart()
		{
			$this->_session = array();
		}
	}
CLASSE PRODUCT
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# ##############################################################################
# INTERFACES
# ##############################################################################
	interface Vendable
	{
		// interface utilisée par la classe Panier
		public function getName();
		public function getPrice();
		public function getRef();
		public function getFamily();
	}
 
 
 
 
# ##############################################################################
# CLASS
# ##############################################################################
	class Product implements Vendable
	{
		protected $_name;
		protected $_price;
		protected $_reference;
		protected $_product_family;
 
		public function __construct($product_family, $name, $price, $ref)
		{
			$this->_name  = (string)$name;
			$this->setPrice($price);
			$this->setReference($ref);
			$this->setFamily($product_family);
		}
 
		public function getPrice()
		{
			return $this->_price;
		}
 
		public function getName()
		{
			return $this->_name;
		}
 
		public function getRef()
		{
			if ( empty($this->_reference) ) {
				$this->_reference = 'not defined';
			}
			return $this->_reference;
		}
 
		public function getFamily()
		{
			if ( empty($this->_product_family) ) {
				$this->_product_family = 'not defined';
			}
			return $this->_product_family;
		}
 
		public function setPrice($p)
		{
			if (is_numeric ( $p)) {
				$this->_price = round( abs((float)$p), 3) ;
			}
			else {
				$this->_price = 0 ;
			}
			return $this;
		}
 
		public function setReference($ref)
		{
			$this->_reference = htmlspecialchars ( $ref) ;
			return $this;
		}
 
		public function setFamily($fam)
		{
			$this->_product_family = strtoupper($fam) ;
			return $this;
		}
 
 
		// Ajouter Destructeur
 
	} /* fin Product */
CLASSE PANIER
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
	class Panier
	{
		protected $_stockage;
 
		public function __construct(Stockage $s = null)
		{
			if ($s == null) {
				$s = new SessionStockage("cart");
			}
			$this->setStockage($s);
		}
 
		public function setStockage(Stockage $s)
		{
			$this->_stockage = $s;
			return $this;
		}
 
		public function getStockage()
		{
			return $this->_stockage;
		}
 
		public function addProduct(Vendable $produit, $qte = 1, $reduction = 0)
		{
			if ( (!isset($qte)) || ($qte <= 0) || ($qte > 1000) ) { $qte = 1; }
			$reduction = abs((int)$reduction);
			if ($reduction > 100) {$reduction = 100;}
			$this->_stockage->set( $produit->getName(), $qte * ($produit->getPrice() - $produit->getPrice() * $reduction/100) );
		}
 
		public function removeProduct(Vendable $p)
		{
			$this->_stockage->delete($p->getName());
			return $this;
		}
 
 
		public function facture()
		{
			return $this->_stockage->total();
		}
 
		public function flush_cart()
		{
			$this->_stockage->flush_cart();
			return $this;
		}
	}
L'index qui manipule ces 3 classes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
 
require_once("../lib/fonction_classes.php");
spl_autoload_register ('LoadPHPClass');
error_reporting(E_ALL);
 
 
// STOCKAGE
	$storage_session = new SessionStockage('cart');
	// ou $stockage = new DatabaseStockage(...);
 
// PRODUITS
	$produit[] = new Product($product_family = 'pack','pack truc', '2.3991' ,'PK-00113') ;
	$produit[] = new Product($product_family = 'pack','pack truc', '3.92' ,'PK-00114') ;
	$produit[] = new Product($product_family = 'pulls','coll en V', 2.3123 ,'CM-00113') ;
	$produit[] = new Product($product_family = 'pantalons','maxi levis 501', 4.567 ,'') ;
	$produit[] = new Product($product_family = 'T-shirts','Superman', 12.199 ,'AL-00113') ;
 
	echo '<br/><b>PRODUITS</b>';
	echo '<table style="border:solid 1px;">';
	echo '<thead>';
		echo '<tr>';
			echo '<td>Key</td>';echo '<td>Family</td>'; echo '<td>Name</td>'; echo '<td>Price</td>'; echo '<td>Ref</td>';
		echo '</tr>';
	echo '</thead>';
 
	foreach ($produit as $key => $product_n) {
		echo '<tr>';
			echo  '<td>P'. $key . '</td>';
			echo '<td>' . $product_n->getFamily() . '</td>';
			echo '<td>' . $product_n->getName() . '</td>';
			echo '<td>' . $product_n->getPrice() . ' Euros' . '</td>';
			echo '<td>' .$product_n->getRef() . '</td>'; 
		echo '</tr>';
	}
	echo '</table>';
 
 
 
// PANIER
 
	// Remplissage du panier
	$panier = new Panier($storage_session);
	foreach ($produit as $product ) {
		$panier->addProduct( $product, $quant = 2, $remise = 0);
	}
 
	// Affichage Montant
	echo '<br/><br/><b>PANIER</b>';
	echo '<br/>Facture : '. $panier->facture() . '<br/>';
 
	// Suppression d'un produit (avec ses quantités ds le panier)
	echo  '<br/>Suppression des produits <b>' . $produit[0]->getName() . '</b> ('. $produit[0]->getRef() . ') du panier ' ;
	$panier->removeProduct($produit[0]);
	echo '<br/>Nouvelle Facture : '. $panier->facture() . '<br/>';
	// ce n'est justement pas le but mais aussi accessible par : var_dump($_SESSION['cart']) ;
 
	// Ajout d'un produit
	echo  '<br/>Ajout du produit <b>' . $produit[0]->getName() . '</b>' ;
	$panier->addProduct($produit[0], $quant = 2, $remise = 0);
	echo '<br/>Nouvelle Facture : '. $panier->facture() . '<br/>';
 
	// Modification d'un produit
	echo  '<br/>Modification du prix du produit <b>' . $produit[0]->getName() . '</b>' ;
	echo '<br/>nota: il faut d abord le supprimer du panier, creer le nouveau produit ou plus simplement le modifier puis l ajouter au panier' ;
	$panier->removeProduct($produit[0]);
 
	$produit[0]->setPrice(6.5);
 
	$panier->addProduct($produit[0], $quant = 2, $remise = 0);
	echo '<br/>Nouvelle Facture : '. $panier->facture() . '<br/>';
 
	echo '<br/><br/><b>STOCKAGE</b>';
	// Suppression directe dans le stockage => interaction directe sur le panier
	echo  '<br/>Suppression directe dans le stockage => Interaction avec panier : on supprime le produit (par son nom) <b>' . $produit[0]->getName() . '</b>' ;
	$storage_session->delete($produit[0]->getName());
	echo '<br/>Nouvelle Facture : '. $panier->facture() . '<br/>';
 
	// Modification directe dans le stockage => interaction directe sur le panier
	echo  '<br/>Modification du stockage => Interaction avec panier ; on modifie le prix produit de <b>' . $produit[0]->getName() . '</b>' ;
	$storage_session->set($produit[0]->getName(), $new_price = 1.0 );
	echo '<br/><b>Attention</b>: pas d\'interaction inverse avec la classe Product. Preuve: Le prix inchangé du produit dans cette classe = ' . $produit[0]->getPrice();
	echo '<br/>Nouvelle Facture : '. $panier->facture() . '<br/>';
 
	// Vidage du panier
	echo '<br/><br/><b>PANIER</b>';
	echo '<br/>Vidage total du panier';
	$panier->flush_cart();
	echo '<br/>Nouvelle Facture : '. $panier->facture() . '<br/>';