Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > Templates > Smarty
Smarty Forum d'entraide sur le moteur de templates Smarty. Avant de poster -> FAQ Smarty et Cours Smarty
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 22/12/2011, 19h28   #1
Invité de passage
 
alfaiate olivier
Inscription : décembre 2011
Messages : 5
Détails du profil
Informations personnelles :
Nom : alfaiate olivier
Localisation : France, Essonne (Île de France)

Informations forums :
Inscription : décembre 2011
Messages : 5
Points : 0
Points : 0
Par défaut Problème de récupération de données dans un foreach (hors tpl)

Bonjour à tous,

Je travaille actuellement sur un site que je dois remettre à niveau, et qui est basé sur Smarty, mais j'ai un problème pour récupérer des données dans une boucle forEach en php (pas dans le tpl mais dans le module qui récupère les données de la classe correspondante). Je cherche à créer une galerie photos avec albums, le nom des albums sont stockés dans la bd, et je récupère la liste des photos grâce à la fonction Glob.
Mais mon forEach n'affiche que le dernier enregistrement de ma table albums.
C'est sûrement un problème d'indexation, mais je n'arrive pas à m'en sortir, je suis un peu largué...

Donc :

j'ai une classe "Photos" photos.class.php qui récupère le nom des albums photos dans la base de données sql, que voici :

Code :
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
 
class Photos
{
	private $id, $nom, $description;
 
	/**
	 * Constructeur
	 *
	 * @param integer $id L'identifiant
	 */
	public function __construct($id)
	{
		$this->id = $id;
 
		$db = DB::getSingleton(WEBFC_SQL_TYPE);
		$sql = "SELECT * FROM `albums` WHERE id = $id";
		$rs = $db->query($sql);
 
		if ($row = $db->fetchArray($rs))
		{
			$this->id 	= $row["id"];
			$this->nom 	= $row["nom"];
			$this->description 	= $row["description"];
		}
 
		$db->free($rs);	
	}
 
 
	public function getNom()
	{
		return $this->nom;
	}
 
	public function getId()
	{
		return $this->id;
	}
 
	public function getDesc()
	{
		return $this->description;	
	}
 
	public static function getItems()
	{
		$list = array();
		$db = DB::getSingleton(WEBFC_SQL_TYPE);
 
		$sql = "SELECT `id` FROM `albums` ORDER BY `id` ASC";
		$rs = $db->query($sql);
 
 
		while ($row = $db->fetchArray($rs))
		{
 
			$p = new Photos($row['id']);
			array_push($list, $p);
 
		}
 
		$db->free($rs);
		return $list;		
	}
}


J'ai ensuite un module fo_medias.php où la classe est appelée et qui gère les données qui seront envoyées au template, dans ce module j'ai :

Code :
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
 
$photos = Photos::getItems();
 
 
foreach ($photos as $p) {
	//$listeAlbum[$p->getId()] = $p->getNom();
	//$listeAlbum[] = $p->getNom();
 
 
//path to directory to scan
$thumbnails = "files/image/medias/photos/".$p->getNom()."/thumbs/"; 
$large = "files/image/medias/photos/".$p->getNom()."/";
 
//get all image files with a .jpg extension.
$imagesThumbnails = glob($thumbnails. "*.jpg");
$imagesLarge = glob($large. "*.jpg");
 
$filecount = count(glob($thumbnails. "*.jpg"));
 
}
 
 
$template->assign("imagesThumbnails", $imagesThumbnails);
$template->assign("imagesLarge", $imagesLarge);
$template->assign("thumbPagination", $thumbPagination);
$template->assign("filecount", $filecount);
$template->assign("photos", $photos);
c'est là où ça coince, le forEach me retourne uniquement le dernier enregistrement


et enfin j'affiche le tout dans mon tpl medias.tpl :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
{foreach from=$photos item=entry name=link}	
	<div id="liensPhotos">
	<div id="pagination" class="pagination">{$thumbPagination}</div>
	<h1 class="titre" onclick="closePhotos()"><img src="templates/images/photo.png" style="vertical-align: -10%;" /> {$entry->getNom()} <span>{if $filecount > 0} /// {$filecount} {if $filecount == 1}photo{else}photos{/if} actuellement{else} /// Aucune photo actuellement{/if}</span></h1>
 
		<ul>
			{foreach from=$imagesThumbnails item=Thumbs name=thumbList}
				<li><a href="{$imagesLarge[$smarty.foreach.thumbList.index]}" rel="lightbox_gal"><img src="{$Thumbs}" class="thumbs" border="0"/></a></li>
			{/foreach}			
		</ul>
	</div>
{/foreach}
un petit screen du résultat obtenu :


ma liste d'albums est ok, par contre ça ne récupère que les photos qui correspondent au dernier dossier, l'erreur vient je pense de mon forEach dans le modules fo_media.php, et pas du tpl, mais je ne m'en dépatouille pas...

Si quelqu'un pouvait me dire où ça coince, ça serait génial !!

Merci d'avance pour votre aide.

Olivier
alfazzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/12/2011, 21h10   #2
Membre Expert
 
Avatar de eric.pommereau
 
Homme ERIC POMMEREAU
Ingénieur intégration
Inscription : décembre 2004
Messages : 683
Détails du profil
Informations personnelles :
Nom : Homme ERIC POMMEREAU
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Ingénieur intégration
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : décembre 2004
Messages : 683
Points : 1 294
Points : 1 294
Bonjour,

Oui c'est ton foreach qui déconne je pense.

Code :
1
2
3
//path to directory to scan
$thumbnails = "files/image/medias/photos/".$p->getNom()."/thumbs/"; 
$large = "files/image/medias/photos/".$p->getNom()."/";
Ce code n'est pas nécéssaire, il suffit de passer les chemins au moteur de template et d'accéder aux méthodes (getNom()) dans le TPL.

Code :
1
2
3
4
5
//get all image files with a .jpg extension.
$imagesThumbnails = glob($thumbnails. "*.jpg");
$imagesLarge = glob($large. "*.jpg");
 
$filecount = count(glob($thumbnails. "*.jpg"));
ça devrait être en dehors du foreach, tu refais le même traitement pour chaque image.

L'idéal est de bien préparer la structure des données en PHP pour les consommer facilement dans le template.

Enfin pour savoir quelles sont les données dispos dans le TPL, il te suffit d'écrire {debug} n'importe où dans le template.

Bonne soirée.
eric.pommereau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/12/2011, 02h38   #3
Invité de passage
 
alfaiate olivier
Inscription : décembre 2011
Messages : 5
Détails du profil
Informations personnelles :
Nom : alfaiate olivier
Localisation : France, Essonne (Île de France)

Informations forums :
Inscription : décembre 2011
Messages : 5
Points : 0
Points : 0
Merci Eric,
j'ai retiré les fonctions glob de mon foreach, par contre je n'arrive toujours pas à sortir la liste des images correspondant aux dossiers de ma table "albums".

Citation:
Ce code n'est pas nécéssaire, il suffit de passer les chemins au moteur de template et d'accéder aux méthodes (getNom()) dans le TPL.
mais si j'enlève ce bout de code, comment la fonction glob va savoir où aller chercher la liste des images, à moins de la mettre (la fonction glob) directement dans le template entre des balises {php}{/php}, là du coup je pourrais récupérer la valeur de chaque dossier et boucler pour afficher les images correspondantes, mais je perd l'intérêt de la logique smarty dans ce cas là ?

Bref je bloque complètement, je crois bien avoir compris la logique, mais pas la pratique...
Pour chaque nom d'albums je dois créer le chemin correspondant pour que la fonction glob sache où aller chercher les images, donc dans ma logique je dois créer une boucle pour afficher le chemin de chaque dossier.

Bon je suis certainement pas loin de trouver une solution, mais j'avoue qu'un petit coup de pouce me ferait bien avancer, car j'ai l'impression de tourner en rond depuis cet après midi, et franchement je crois que là mon niveau est confronté à ses limites, d'autant que c'est la première fois que je travaille en "profondeur" sur un site géré par Smarty, j'ai bien un peu trafiquoté sur du prestashop, mais cela restait très succins...

Sur ce je crois que j'ai besoin d'une bonne nuit de sommeil !!

Encore merci de vous attarder sur mon problème et bonne nuit (et à demain j'espère...)
alfazzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/12/2011, 08h27   #4
Membre Expert
 
Avatar de eric.pommereau
 
Homme ERIC POMMEREAU
Ingénieur intégration
Inscription : décembre 2004
Messages : 683
Détails du profil
Informations personnelles :
Nom : Homme ERIC POMMEREAU
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Ingénieur intégration
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : décembre 2004
Messages : 683
Points : 1 294
Points : 1 294
Code :
mais si j'enlève ce bout de code, comment la fonction glob va savoir où aller chercher la liste des images, à moins de la mettre (la fonction glob) directement dans le template entre des balises {php}{/php}, là du coup je pourrais récupérer la valeur de chaque dossier et boucler pour afficher les images correspondantes, mais je perd l'intérêt de la logique smarty dans ce cas là ?
{php}{/php} n'est jamais une bonne idée. Il faut respecter le principe de la séparation affichage/production de données.

Effectivement tes fonction glob sont nécéssaires mais quand tu écris ça :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
foreach ($photos as $p) {
...
//get all image files with a .jpg extension.
$imagesThumbnails = glob($thumbnails. "*.jpg");
$imagesLarge = glob($large. "*.jpg");
 
$filecount = count(glob($thumbnails. "*.jpg"));
}
 
$template->assign("imagesThumbnails", $imagesThumbnails);
$template->assign("imagesLarge", $imagesLarge);
$template->assign("thumbPagination", $thumbPagination);
$template->assign("filecount", $filecount);
--> Les valeurs sont remplacées à chaque itération de foreach, c'est donc la dernière image qui est prise en compte.

Ta classe photo devrait prendre en charge la gestion des vignettes associées. Cela faciliterait la récupération dans le TPL.

La solution est donc du ressort de PHP.

Voilà à toi de jouer.
eric.pommereau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/12/2011, 20h28   #5
Invité de passage
 
alfaiate olivier
Inscription : décembre 2011
Messages : 5
Détails du profil
Informations personnelles :
Nom : alfaiate olivier
Localisation : France, Essonne (Île de France)

Informations forums :
Inscription : décembre 2011
Messages : 5
Points : 0
Points : 0
Bon je laisse tomber, j'y arrive pas, j'ai essayé de gérer l'appel de mes vignettes dans ma classe comme tu me l'as conseillé, et j'arrive à récupérer le chemin de chaque dossier dans mon tpl, mais je ne parviens plus à scanner la liste des images avec la fonction glob en fonction du chemin.
Je m'y prend sûrement pas de la bonne façon et je finis par m'embrouiller et ne ne pas avancer, ça me décourage!!

Tout ce que j'ai réussi à faire c'est créer des fonctions pour renvoyer le chemin des dossiers ( getThumbsUrl() et getLargeUrl() ), mais c'est tout...

Code :
1
2
3
4
5
6
7
 
public function getThumbsUrl()	
{
$thumbnails= "files/image/medias/photos/"'.this->nom.'"/thumbs/";
$imagesThumbnails = glob($thumbnails. "*.jpg");
return $imagesThumbnails;	
}
et j'arrive bien dans la boucle foreach du tpl à récupérer les bons chemins, par contre j'arrive pas à avoir la liste des images correspondantes, j'ai essayé dans tout les sens (en fonction de mes connaissances bien sûr), mais sans succès.

Donc pour l'instant, le client n'aura pas de galerie avec albums (dommage car côté back-office c'est opérationnel), mais juste une galerie simple avec une liste d'images.

Smarty est encore trop obscure pour moi, j'ai pas forcement assimilé la logique.
Le site sur lequel je travaille n'a pas été crée par moi, et même si j'ai réussi avec succès à modifier les templates et à créer de nouvelles fonctionnalités malgré Smarty, là je câle !!!

Encore merci Eric d'avoir pris le temps de regarder mon problème, si tu as une solution directe je suis évidement preneur (mais je comprend bien que pédagogiquement il serait plus instructif de trouver la solution par moi même, mais malgré tes conseils et orientations, je n'y arrive pas...et le site sera en ligne demain soir).

Bon à la base je devais uniquement faire une simple galerie pour mon client, donc le contrat est tout de même remplis...

Cordialement
Olivier
alfazzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/12/2011, 21h18   #6
Membre Expert
 
Avatar de eric.pommereau
 
Homme ERIC POMMEREAU
Ingénieur intégration
Inscription : décembre 2004
Messages : 683
Détails du profil
Informations personnelles :
Nom : Homme ERIC POMMEREAU
Âge : 38
Localisation : France

Informations professionnelles :
Activité : Ingénieur intégration
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : décembre 2004
Messages : 683
Points : 1 294
Points : 1 294
Je ne peux pas te donner de solution toute faite.

Tout ce que je peux dire c'est que ton TPL doit consommer les données des photos le plus simplement possible.

Pour chaque item ($entry dans ton template) tu dois avoir une liste des thumbnails qui correspondent.

Il faut donc que, pour chaque objet photo, une méthode te retourne les thumbnails pour que dans le TPL tu puisses imbriquer les foreach.

Avant de regarder du côté de Smarty je te conseille de voir si tes données sont bien là en PHP (var_dump). Une fois que tu as bien "tes petits" en PHP tu peux te concentrer sur le TPL.

Bonne soirée et bonnes fêtes.
eric.pommereau est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/12/2011, 23h08   #7
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 462
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 462
Points : 2 552
Points : 2 552
Envoyer un message via Skype™ à rawsrc
Bonsoir,

j'ai repris ta classe Photos en la modifiant.
Tu peux essayer avec ceci :
Code :
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
class Photos
{
   private $id;
   private $nom;
   private $description;
 
   /**
    * @param int $id L'identifiant
    * @param string $nom
    * @param string $description
    */
   public function __construct($id, $nom, $description) {
      $this->id = $id;
      $this->nom = $nom;
      $this->description = $description;
   }
 
   public function getNom() {
      return $this->nom;
   }
 
   public function getId() {
      return $this->id;
   }
 
   public function getDesc() {
      return $this->description;
   }
 
   public static function getItems() {
      $list = array();
      $db = DB::getSingleton(WEBFC_SQL_TYPE);
      $sql = "SELECT id, nom, description FROM albums ORDER BY id ASC";
      $rs = $db->query($sql);
      while ($row = $db->fetchArray($rs)) {
         $list[] = new Photos($row['id'], $row['nom'], $row['description']);
      }
      $db->free($rs);
      return $list;
   }
}
Après avoir étudié ton code, je pense que ton problème vient du fait que tu clôtures ta connexion à chaque fois que tu crées une classe Photos et c'est préjudiciable dans la mesure où tu utilises un singleton.
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/12/2011, 00h29   #8
Invité de passage
 
alfaiate olivier
Inscription : décembre 2011
Messages : 5
Détails du profil
Informations personnelles :
Nom : alfaiate olivier
Localisation : France, Essonne (Île de France)

Informations forums :
Inscription : décembre 2011
Messages : 5
Points : 0
Points : 0
bon j'insiste un peu quand même...

dans ma classe Photos j'ai ajouté 2 fonctions :

Code :
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
 
	public static function getThumbsUrl()	
	{
		$listThumbs = array();
 
		$db = DB::getSingleton(WEBFC_SQL_TYPE);
 
		$sql = "SELECT * FROM `albums` ORDER BY `id` ASC";
		$rs = $db->query($sql);
 
 
		while ($row = $db->fetchArray($rs))
		{
 
			//path to directory to scan
			$thumbnails = "files/image/medias/photos/".$row['nom']."/thumbs/"; 
 
			$t = $thumbnails ;
			array_push($listThumbs, $t);
 
		}
 
		$db->free($rs);
		return $listThumbs;
	}
 
 
 
 
 
 
 
	public static function getLargeUrl()	
	{
		$listLarge = array();
 
		$db = DB::getSingleton(WEBFC_SQL_TYPE);
 
		$sql = "SELECT * FROM `albums` ORDER BY `id` ASC";
		$rs = $db->query($sql);
 
 
		while ($row = $db->fetchArray($rs))
		{
 
			//path to directory to scan
			$large = "files/image/medias/photos/".$row['nom']."/"; 
 
			$l = $large ;
			array_push($listLarge, $l);
 
		}
 
		$db->free($rs);
		return $listLarge;
	}

Dans mon module j'ai rajouté ces lignes :
Code :
1
2
3
4
5
6
 
$thumbsList = Photos::getThumbsUrl();
$largeList = Photos::getLargeUrl();
 
$template->assign("thumbsList", $thumbsList);
$template->assign("largeList", $largeList);

et dans mon tpl, si je fais ça :
Code :
1
2
3
4
5
 
{foreach from=$thumbsList item=thumbsUrl name=list}	
	{$thumbsUrl}
	{$largeList[$smarty.foreach.list.index]}
{/foreach}
et je récupère bien les chemins des dossiers :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
files/image/medias/photos/test/thumbs/ 
files/image/medias/photos/test/ 
files/image/medias/photos/test2/thumbs/ 
files/image/medias/photos/test2/ 
files/image/medias/photos/foot/thumbs/ 
files/image/medias/photos/foot/ 
files/image/medias/photos/tournois/thumbs/ 
files/image/medias/photos/tournois/ 
files/image/medias/photos/mon album/thumbs/ 
files/image/medias/photos/mon album/ 
files/image/medias/photos/tset3/thumbs/ 
files/image/medias/photos/tset3/
Donc ça progresse un peu, là où je bloque, c'est pour la fonction glob, je vois pas où la placer, j'ai essayé différentes chose, mais je n'obtiens pas ce qu'il faut en sortie.

mais...j'vais y arriver, j'vais y arriver...
alfazzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/12/2011, 00h39   #9
Invité de passage
 
alfaiate olivier
Inscription : décembre 2011
Messages : 5
Détails du profil
Informations personnelles :
Nom : alfaiate olivier
Localisation : France, Essonne (Île de France)

Informations forums :
Inscription : décembre 2011
Messages : 5
Points : 0
Points : 0
Citation:
Envoyé par rawsrc Voir le message
Bonsoir,

j'ai repris ta classe Photos en la modifiant.
Tu peux essayer avec ceci :
Code :
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
class Photos
{
   private $id;
   private $nom;
   private $description;
 
   /**
    * @param int $id L'identifiant
    * @param string $nom
    * @param string $description
    */
   public function __construct($id, $nom, $description) {
      $this->id = $id;
      $this->nom = $nom;
      $this->description = $description;
   }
 
   public function getNom() {
      return $this->nom;
   }
 
   public function getId() {
      return $this->id;
   }
 
   public function getDesc() {
      return $this->description;
   }
 
   public static function getItems() {
      $list = array();
      $db = DB::getSingleton(WEBFC_SQL_TYPE);
      $sql = "SELECT id, nom, description FROM albums ORDER BY id ASC";
      $rs = $db->query($sql);
      while ($row = $db->fetchArray($rs)) {
         $list[] = new Photos($row['id'], $row['nom'], $row['description']);
      }
      $db->free($rs);
      return $list;
   }
}
Après avoir étudié ton code, je pense que ton problème vient du fait que tu clôtures ta connexion à chaque fois que tu crées une classe Photos et c'est préjudiciable dans la mesure où tu utilises un singleton.
Merci pour ton aide, j'étais en train de faire une réponse, je viens de voir ton post.
Pourrais tu regarder mon message précédent, car j'ai un peu avancé, avant que je me penche sur ta solution ?
alfazzz est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h55.


 
 
 
 
Partenaires

Hébergement Web