The user_id shows up three times in the mealplans table so this prints out the name of the contributor three times. How can I re-write this so it only prints out once?
I have the following code in templates/Mealplans/index.php:
<h1>Meal Plans for
<?php
foreach ($users as $user):
foreach ($mealplans as $mealplan):
if ($user->id == $mealplan->user_id){
echo $user->contributor;
}
endforeach;
endforeach;
?></h1>
This displays:
Meal Plans for MaureenMaureenMaureen
in the browser
Youâre better off asking what output you want.
Did you only want the list of users who have a meal plan?
Did you want to show what all those meal plans are?
There may well be a faster & simpler way of doing what you want here.
I suspect you should be building this as a nested query in the controller, and just passing that result set to the template (have the controller do the heavy lifting) - then you need only loop over that result - your loop is complexity O(n^2).
If you can post your table structures of both users & mealplan we can show you what code to write to make it faster and cleaner.
To answer your question outright, put a break; line after your echo. That is the answer, but just saying its the wrong approach.
If youâre only looking to output one user, why do you have $users instead of just $user? As @Jawfin said, it seems like maybe itâs your query thatâs wrong, moreso than your view.
Assuming youâre using the authentication you will have the user_id in that object.
I only know CakePHP 4, so not sure if itâll be different in other versions, but you can get that directly in any controller. You could do something like this AppController in beforeFilter() so itâs available in all templates and all other controllers.
$data = $this->Authentication->getResult()->getData(); //actual user entity, null when not logged in
$this->isLoggedIn = $this->Authentication->getResult()->isValid();
$this->loggedInID = $this->isLoggedIn ? $data->id : -1;
$this->loggedInEmail = $this->isLoggedIn ? h($data->email) : "";
$this->contributor = $this->isLoggedIn ? h($data->contributor) : ""; //should work if your Model/Entity/User.php has this in $_accessible
$this->set(['isLoggedIn' => $this->isLoggedIn,
'loggedInID' => $this->loggedInID,
'loggedInEmail' => $this->loggedInEmail,
'contributor' => $this->contributor,
]);
This allows access to these variables in the template as youâre doing, but it can be done inline: -
<!-- HTML -->
<h1>Meal Plans for <?= $contributor ?></h1>
And in all your actions in all your controllers those fields can be accessed as they are set here within the parent app object, like $this->contributor which can save you loading the User model and doing a find just for a field which is already present in your authorization object.
This all means, of course, that your actual title of your question is no longer relevant, as we arenât even looping, let alone a nested one, to get this info.
Please donât take offence to this next comment: but this is programming, and I feel you should get some formal training for your code design, object oriented, algorithms, usage & scope of variables - just the whole gamut really :\
Bah, sorry to hear that. If you could turn on debugging and see if its firing up any errors. As youâve changed the user table from the CMS tut make sure youâve cleared the cache so the new structure comes through, via: bin/cake cache clear_all
And check your user entity actually has the contributor field. If its how you think it should be, try simpler, comment out the code except for say the isLoggedIn stuff and pass that variable and echo it. Then try for the email, etc. Get it working on something simple then incrementally expand to what your goal is.
Imagine CakePHP as its own language; youâre not going to get by without understanding it - its not friendly to just dumping in pasted code found elsewhere. Its like writing a novel in a language you donât know and that was the approach taken. (Actually, that analogy applies to all languages!)
Thanks, Jawfin
When I do <?php dump($contributor)?> it prints out ^ ââ
There is noone in the users table with that contributor name
When I use debug($contributor);, it doesnât print out anything.
In the tutorial: Debugging - 4.x
He writes: âOutput from this function is only shown if the core $debug variable has been set to true.â
Where can I find where to set $debug to true?
Use debug($this->contributor); in your AppController after the line where you set itâs value.
Thereâs little point in doing it in the template as you know itâs not getting that far anyway. But it is handy if you need to dump a whole object.
If youâre working in your own play environment you can enable the debugger in config/app_local.php by setting âdebugâ & âDebugKit.forceEnableâ to true. You may also need to set âDebugKit.ignoreAuthorizationâ to true too if you are testing and want to bypass authorization.
I still get the feeling youâre trying to get this to work via brute force and not understanding it.
Also, never, ever set those debug variables to true on a web-facing site. There are ways you can debug live - and if you need to do that make another thread in that regard.
When I do debug($this->contributor); in the AppController I get the message: Cannot modify header information - headers already sent All of the sites that I have googled say this is a result of re-directing. When I do var_dump($this->contributor); in the AppController, I get: string(0) ââ
Iâm just replying now as I wonât get the chance later. Maybe beforeFilter() is not the place to sneak a debug in; perhaps try putting it at the start if the action the controller its using. Also check youâre using var_dump [not dump] for when youâre not using debug (but in the templates only).
The redirect may possibly be the authorization kicking in, so check âDebugKit.ignoreAuthorizationâ is true too. I may be missing something fundamental in my attempts to help, so hopefully someone else who knows more may have a idea!
I think the reason that var_dump() is returning string(0) ââ is that nobody is logged in. I get the error: âInvalid email or passwordâ when I try to log in so that has to be fixed as well.